/*
* Copyright 2012 Phil Pratt-Szeliga and other contributors
* http://chirrup.org/
*
* See the file LICENSE for copying permission.
*/
package org.trifort.rootbeer.generate.opencl.body;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.trifort.rootbeer.util.Stack;
import soot.Body;
import soot.Local;
import soot.Unit;
import soot.Value;
import soot.jimple.EnterMonitorStmt;
import soot.jimple.ExitMonitorStmt;
import soot.toolkits.graph.ExceptionalBlockGraph;
import soot.toolkits.graph.Block;
public class MonitorGroups {
public List<MonitorGroupItem> getItems(Body body){
//TODO: Look at
/*
ExceptionalBlockGraph graph = new ExceptionalBlockGraph(body);
System.out.println("========================================");
System.out.println("= blocks");
System.out.println("========================================");
List<Block> blocks = graph.getBlocks();
for(Block block : blocks){
System.out.println(block);
}
System.out.println("========================================");
*/
List<MonitorGroupItem> ret = new ArrayList<MonitorGroupItem>();
Stack<MonitorGroupItem> stack = new Stack<MonitorGroupItem>();
MonitorGroupItem curr_monitor = new MonitorGroupItem();
ret.add(curr_monitor);
stack.push(curr_monitor);
List<Unit> units = getUnits(body);
for(int i = 0; i < units.size(); ++i){
Unit curr = units.get(i);
if(curr instanceof EnterMonitorStmt){
MonitorGroupItem item = new MonitorGroupItem();
item.addEnterMonitor(curr);
stack.top().addGroup(item);
stack.push(item);
MonitorGroupItem item2 = new MonitorGroupItem();
stack.top().addGroup(item2);
stack.push(item2);
} else if(curr instanceof ExitMonitorStmt){
if(isLastExit((ExitMonitorStmt) curr, i, units)){
stack.top().addUnit(curr);
stack.pop();
stack.pop();
stack.pop();
if(stack.size() == 0){
curr_monitor = new MonitorGroupItem();
ret.add(curr_monitor);
stack.push(curr_monitor);
} else {
curr_monitor = new MonitorGroupItem();
stack.top().addGroup(curr_monitor);
stack.push(curr_monitor);
}
} else {
stack.top().addUnit(curr);
}
} else {
stack.top().addUnit(curr);
}
}
return ret;
}
private boolean isLastExit(ExitMonitorStmt exit, int index, List<Unit> units){
Value op = exit.getOp();
Local op_local = (Local) op;
for(int j = index + 1; j < units.size(); ++j){
Unit curr = units.get(j);
if(curr instanceof EnterMonitorStmt){
return true;
} else if(curr instanceof ExitMonitorStmt){
ExitMonitorStmt exit2 = (ExitMonitorStmt) curr;
Local op_local2 = (Local) exit2.getOp();
if(op_local.getName().equals(op_local2.getName())){
return false;
}
}
}
return true;
}
private List<Unit> getUnits(Body body){
List<Unit> ret = new ArrayList<Unit>();
Iterator<Unit> iter = body.getUnits().iterator();
while(iter.hasNext()){
Unit curr = iter.next();
ret.add(curr);
}
return ret;
}
private void print(List<MonitorGroupItem> ret) {
for(MonitorGroupItem item : ret){
System.out.println("<group_item>");
System.out.println("<prefix>");
List<Unit> prefix = item.getPrefixUnits();
for(Unit pre : prefix){
System.out.println(pre.toString());
}
System.out.println("</prefix>");
if(item.getEnterMonitor() != null){
System.out.println("<enter>");
System.out.println(item.getEnterMonitor().toString());
System.out.println("</enter>");
}
print(item.getGroups());
System.out.println("</group_item>");
}
}
}