blob: 0fce3de19a8612f952f1eec157a25b15c809ded4 [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;
}
//@formatter:off
/**
* 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.
* <br>
* BRT clarification: 09/09/09<br>
* OpenMPI < 1.3? defines MPI_COMM_WORLD as:<br>
* #define MPI_COMM_WORLD (&ompi_mpi_comm_world)<br>
* OpenMPI 1.3.3 defines MPI_COMM_WORLD as:<br>
* #define MPI_COMM_WORLD OMPI_PREDEFINED_GLOBAL( MPI_Comm, ompi_mpi_comm_world)<br>
* 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?
*/
//@formatter:on
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_;
}
}
}