// $Id: mayWriteAnalyzer.java,v 1.2 2000/11/14 09:44:28 msato Exp $
// $RWC_Release: Omni-1.6 $
// $RWC_Copyright:
//  Omni Compiler Software Version 1.5-1.6
//  Copyright (C) 2002 PC Cluster Consortium
//  
//  This software is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License version
//  2.1 published by the Free Software Foundation.
//  
//  Omni Compiler Software Version 1.0-1.4
//  Copyright (C) 1999, 2000, 2001.
//   Tsukuba Research Center, Real World Computing Partnership, Japan.
//  
//  Please check the Copyright and License information in the files named
//  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
//  Software release kit.
//  
//  
//  $

package ompd;

import exc.object.*;
import exc.block.*;
import exc.openmp.*;
import exc.flow.*;
import exc.util.*;

public class mayWriteAnalyzer implements DataFlowSets {
  NumberSet Gen[];
  NumberSet Kill[];
  NumberSet In[];
  NumberSet Out[];

  int max_index;

  public void run(optBodyEnv env,int num_shared_obj){
    run(env.getCFG(),num_shared_obj);
  }

  public void run(ControlFlowGraph cfg,int num_shared_obj){
    max_index = num_shared_obj+1;

    int nBlock = cfg.numOfBasicBlock();
    Gen = new NumberSet[nBlock];
    Kill = new NumberSet[nBlock];
    In = new NumberSet[nBlock];
    Out = new NumberSet[nBlock];

    setupWriteSet(cfg);

    cfg.solveForwardUnionFlow(this);
  }

  void setupWriteSet(ControlFlowGraph cfg){
    for(BasicBlock bb = cfg.getHead(); bb != null; bb = bb.topNext()){
      int id = bb.Id();
      if(!bb.isEmpty()){
	NumberSet write_set = NumberSet.empty(max_index);
	for(Statement s = bb.getHead(); s != null; s = s.getNext()){
	  Xobject x = s.getExpr();
	  if(x == null) continue;
	  if(x.Opcode() == RWcheckCode.WCHK){
	    RWcheckCode xx = (RWcheckCode)x;
	    write_set.add(xx.getIndex()+1);
	  }
	}
	Gen[id] = write_set;
      }

      Block b = bb.getParent();
      if((b.Opcode() == Xcode.OMP_FLUSH || b.Opcode() == Xcode.OMP_BARRIER)
	 && ((OMPBlock)b).beginBasicBlock() == bb)
	Kill[id] = NumberSet.full(max_index);
      
      In[id] = NumberSet.empty(max_index);
      Out[id] = NumberSet.empty(max_index);
    }
  }

  /* interface to DataFlowSets */
  public void initSet(BasicBlock bb){ Out[bb.Id()].copy(Gen[bb.Id()]); }
  public Set emptySet(){ return NumberSet.empty(max_index); }
  public Set GenSet(BasicBlock bb){ return Gen[bb.Id()]; }
  public Set InSet(BasicBlock bb){ return In[bb.Id()]; }
  public Set OutSet(BasicBlock bb){ return Out[bb.Id()]; }
  public Set KillSet(BasicBlock bb){ return Kill[bb.Id()]; }

  /* return result */
  public boolean mayWrite(BasicBlock bb,int index){
    return In[bb.Id()].contain(index+1);
  }
}

