blob: 044c8c475be5cf17b0376cd2f37933490a1f97ad [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.List;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.core.resources.IResource;
import org.eclipse.ptp.pldt.common.Artifact;
import org.eclipse.ptp.pldt.common.util.SourceInfo;
public class BarrierTable {
/**
* Set of barriers for a communicator.
* Key: <String>communicator, Value: set of <BarrierInfo>barriers
*/
protected Hashtable<String,List<BarrierInfo>> table_;
protected int commCounter = 0;
private static boolean dbg_barrier=false;
public BarrierTable(){
table_ = new Hashtable<String,List<BarrierInfo>>();
}
public Hashtable<String,List<BarrierInfo>> getTable(){
return table_;
}
public boolean isEmpty() {return table_.isEmpty();}
public BarrierInfo addBarrier(IASTFunctionCallExpression barE,
int id, IResource res, String func){
BarrierInfo bar = new BarrierInfo(barE, id, res, func);
if(table_.containsKey(bar.getComm())){
List<BarrierInfo> list = table_.get(bar.getComm());
list.add(bar);
} else {
List<BarrierInfo> list = new ArrayList<BarrierInfo>();
list.add(bar);
table_.put(bar.getComm(), list);
}
return bar;
}
/**
* @return barrier ID if it is a barrier; -1 otherwise
* <br>BRT barrier ids may not match with OpenMPI 1.3.3 headers?? see setComm()
*/
public int isBarrier(IASTFunctionCallExpression funcE){
IASTExpression funcname = funcE.getFunctionNameExpression();
String signature = funcname.getRawSignature();
if(!signature.equals("MPI_Barrier")) return -1; //$NON-NLS-1$
for(Enumeration e = table_.elements(); e.hasMoreElements();){
ArrayList list = (ArrayList)e.nextElement();
for(Iterator i = list.iterator(); i.hasNext();){
BarrierInfo bar = (BarrierInfo)i.next();
if(bar.getFunc() == funcE)
return bar.getID();
}
}
return -1;
}
public String getComm(int id){
for(Enumeration e = table_.elements(); e.hasMoreElements();){
ArrayList list = (ArrayList)e.nextElement();
for(Iterator i = list.iterator(); i.hasNext();){
BarrierInfo bar = (BarrierInfo)i.next();
if(bar.getID() == id)
return bar.getComm();
}
}
return null;
}
public BarrierInfo searchBarrierbyID(int id){
for(Enumeration e = table_.elements(); e.hasMoreElements();){
ArrayList list = (ArrayList)e.nextElement();
for(Iterator i = list.iterator(); i.hasNext();){
BarrierInfo bar = (BarrierInfo)i.next();
if(bar.getID() == id)
return bar;
}
}
return null;
}
public class BarrierInfo{
protected String comm_ = null;
protected IASTFunctionCallExpression barrier_ = null;
protected int id = -1;
protected String fileName_ = null;
protected SourceInfo sourceInfo_ = null;
protected List<BarrierInfo> matchingSet_ = null;
protected IResource resource_ = null;
protected String enclosingFunc_ = null;
public BarrierInfo(IASTFunctionCallExpression funcE, int id, IResource res, String func){
barrier_ = funcE;
this.id = id;
setComm();
setSourceInfo();
matchingSet_ = new ArrayList<BarrierInfo>();
resource_ = res;
enclosingFunc_ = func;
}
/**
* Determine the communicator from the the barrier function call
* ("MPI_Barrier(communicator)"). <br>
* If the communicator is the default (MPI_COMM_WORLD), then the type of
* the returned object from getOperand() depends on how the header file
* defines it (In windows, it is IASTLiteralExpression, and in Linux, it
* becomes IASTIdExpression). So we account for that here.
*
* BRT clarification: 09/09/09
* OpenMPI < 1.3? defines MPI_COMM_WORLD as:
* #define MPI_COMM_WORLD (&ompi_mpi_comm_world)
* OpenMPI 1.3.3 defines MPI_COMM_WORLD as:
* #define MPI_COMM_WORLD OMPI_PREDEFINED_GLOBAL( MPI_Comm, ompi_mpi_comm_world)
* which makes the CDT objects for the barrier/communicator show up differently when it gets here.
* It shows up as an IASTCastExpression, so we recognize that and get its name,
* instead of relying on the default fallback plan here, which seems to always
* make each barrier/communicator found be unique, in which case no barriers match, because their
* communicators all look different.
*
* Problem: for the case of #define newcomm MPI_COMM_WORLD
* I don't want the getRawSignature() on the communicator arg, i want the
* pre-processed value. How to get that?
*/
protected void setComm() {
IASTExpression parameter = barrier_.getParameterExpression();
IASTInitializerClause[] newParms = barrier_.getArguments(); // BRT could fix deprecation?
if (parameter instanceof IASTUnaryExpression) {
IASTUnaryExpression commExpr = (IASTUnaryExpression) parameter;
IASTExpression commOp=commExpr.getOperand();
if (commOp instanceof IASTUnaryExpression) {
if(dbg_barrier)System.out.println("setComm(): communicator is IASTUnaryExpression"); //$NON-NLS-1$
//IASTUnaryExpression commOprd = (IASTUnaryExpression) commOp;
if (commOp instanceof IASTLiteralExpression) {//Yuan says windows
if(dbg_barrier)System.out.println();
IASTLiteralExpression comm = (IASTLiteralExpression) commOp;
comm_ = comm.toString();
} else if (commOp instanceof IASTIdExpression) { //Yuan says linux
IASTIdExpression comm = (IASTIdExpression) commOp;
comm_ = comm.getName().toString();
} else if (commOp instanceof IASTName) {//?
comm_ = commOp.toString();
} else {
if(commOp instanceof IASTUnaryExpression) {// Mac OSX Openmpi < 1.3 (/usr/include/mpi.h) // 4/14/10: got here OMPI 1.3.3
IASTUnaryExpression iastUnaryExpression = (IASTUnaryExpression) commOp;
if(dbg_barrier)System.out.println("bdbg: communicator is IASTUnaryExpression"); //$NON-NLS-1$
comm_= iastUnaryExpression.getRawSignature();
} else {
// last resort: use a unique name, but it won't
// match anything??
comm_ = "COMM_" + commCounter; //$NON-NLS-1$
commCounter++;
}
}
} else {
if(commOp instanceof IASTCastExpression) {//MAC OSX Openmpi 1.3.3 ;mpich2
IASTCastExpression iastCastExpression = (IASTCastExpression) commOp;
comm_ = iastCastExpression.getRawSignature();
}
else{
comm_ = "COMM_" + commCounter; //$NON-NLS-1$
commCounter++;
}
}
} else if (parameter instanceof IASTIdExpression) {//windows mpich 1.2
IASTIdExpression idE = (IASTIdExpression) parameter;
comm_ = idE.getName().toString();
/* BRT 9/9/09: why hide the actual name? no non-mpi-comm-world comms will match!
if (!comm_.equals("MPI_COMM_WORLD")) {
comm_ = "COMM_" + commCounter;
commCounter++;
}
*/
} else if (parameter instanceof IASTLiteralExpression){// added 9/9/09 for windows/mpich
IASTLiteralExpression iastLiteralExpression = (IASTLiteralExpression) parameter;
String str=iastLiteralExpression.getRawSignature();
comm_=iastLiteralExpression.getRawSignature();
}
else {
comm_ = "COMM_" + commCounter; //$NON-NLS-1$
commCounter++;
}
if(dbg_barrier)System.out.println("setComm(): communicator: "+comm_); //$NON-NLS-1$
}
protected void setSourceInfo() {
IASTExpression funcNameE = barrier_.getFunctionNameExpression();
IASTNodeLocation[] locations = funcNameE.getNodeLocations();
if (locations.length == 1) {
IASTFileLocation astFileLocation = null;
if (locations[0] instanceof IASTFileLocation) {
astFileLocation = (IASTFileLocation) locations[0];
fileName_ = astFileLocation.getFileName();
//System.out.println(fileName_);
sourceInfo_ = new SourceInfo();
sourceInfo_.setStartingLine(astFileLocation.getStartingLineNumber());
sourceInfo_.setStart(astFileLocation.getNodeOffset());
sourceInfo_.setEnd(astFileLocation.getNodeOffset() + astFileLocation.getNodeLength());
sourceInfo_.setConstructType(Artifact.FUNCTION_CALL);
}
}
}
public String getComm() {return comm_;}
public IASTFunctionCallExpression getFunc() {return barrier_;}
public int getID() {return id;}
public String getFileName() {return fileName_;}
public SourceInfo getSourceInfo() {return sourceInfo_;}
public List<BarrierInfo> getMatchingSet() {return matchingSet_;}
public IResource getResource() {return resource_;}
public String getEnclosingFunc() {return enclosingFunc_;}
}
}