// $Id: OMPvar.java,v 1.7 2000/09/27 04:48:33 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 exc.openmp;

import java.io.*;
import exc.object.*;
import exc.block.*;

//
// OMP symbol table, information for each OMP variable
//
public class OMPvar {
  OMPvar next;	// link
  Ident id; 		// key
  int atr;		// original attribute: PRIVATE, SHARED, COPYIN
  boolean is_shared;
  boolean is_private;
  boolean is_first_private;
  boolean is_last_private;
  boolean is_reduction;
  boolean is_copyin;
  int reduction_op;
  Xobject private_addr;	// original base
  Xobject shared_addr;
  Xobject adj_array_size;

  public OMPvar(Ident id,int atr){
    this.id = id;
    this.atr = atr;
    this.next = next;
    if(OMP.debugFlag) 
      System.out.println("OMPvar("+id.getName()+","+
			 OMP.dataAtrName(atr)+")");
    switch(atr){
    case OMP.DATA_SHARED:   /* shared <namelist> */
      is_shared = true;
      break;
    case OMP.DATA_PRIVATE:  /* private <namelist> */
      is_private = true;
      break;
    case OMP.DATA_COPYIN:
      is_copyin = true;
      is_shared = true;
      break;
    case OMP.DATA_FIRSTPRIVATE:
      is_private = true;
      is_shared = true;
      is_first_private = true;
      break;
    case OMP.DATA_LASTPRIVATE:
      is_private = true;
      is_shared = true;
      is_last_private = true;
      break;

    case OMP.DATA_REDUCTION_PLUS:
    case OMP.DATA_REDUCTION_MINUS:
    case OMP.DATA_REDUCTION_MUL:
    case OMP.DATA_REDUCTION_BITAND:
    case OMP.DATA_REDUCTION_BITOR:
    case OMP.DATA_REDUCTION_BITXOR:
    case OMP.DATA_REDUCTION_LOGAND:
    case OMP.DATA_REDUCTION_LOGOR:
    case OMP.DATA_REDUCTION_MIN:
    case OMP.DATA_REDUCTION_MAX:
      is_private = true;
      is_shared = true;
      is_reduction = true;
      reduction_op = atr;
      break;
    }
  }

  Xobject getAddr(){
    if(private_addr != null) return private_addr;
    return shared_addr;
  }

  Xobject Ref(){
    return Xcons.PointerRef(getAddr());
  }

  Xobject getSize() {
    if(adj_array_size != null) return adj_array_size;
    else return Xcons.IntConstant(id.Type().getSize());
  }
    
  Xobject reductionInitValue(){
    int bt;
    switch(reduction_op){
    case OMP.DATA_REDUCTION_PLUS:
    case OMP.DATA_REDUCTION_MINUS:
      if(id.Type().isFloating()) 
	return Xcons.Float(Xcode.FLOAT_CONSTANT,id.Type(),0.0D);
    case OMP.DATA_REDUCTION_BITOR:
    case OMP.DATA_REDUCTION_BITXOR:
    case OMP.DATA_REDUCTION_LOGOR:
      return Xcons.IntConstant(0);

    case OMP.DATA_REDUCTION_MUL:
      if(id.Type().isFloating()) 
	return Xcons.Float(Xcode.FLOAT_CONSTANT,id.Type(),1.0D);
    case OMP.DATA_REDUCTION_LOGAND:
      return Xcons.IntConstant(1);
	    
    case OMP.DATA_REDUCTION_BITAND:
      return Xcons.unaryOp(Xcode.BIT_NOT_EXPR,Xcons.IntConstant(0));

    case OMP.DATA_REDUCTION_MIN:
      if(id.Type().getKind() == Xtype.BASIC)
	bt = id.Type().getBasicType();
      else if(id.Type().isEnum()) bt = BasicType.INT;
      else bt = BasicType.UNDEF;
      switch(bt){
      case BasicType.CHAR:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),0x7F);
      case BasicType.UNSIGNED_CHAR:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),0xFF);
      case BasicType.SHORT:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),0x7FFF);
      case BasicType.UNSIGNED_SHORT:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),0xFFFF);
      case BasicType.SIGNED:
      case BasicType.INT:
      case BasicType.LONG:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),0x7FFFFFFF);
      case BasicType.UNSIGNED_INT:
      case BasicType.UNSIGNED_LONG:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),0xFFFFFFFF);
      case BasicType.FLOAT:
	return Xcons.Float(Xcode.FLOAT_CONSTANT,id.Type(),Float.MAX_VALUE);
      case BasicType.DOUBLE:
	return Xcons.Float(Xcode.FLOAT_CONSTANT,id.Type(),Double.MAX_VALUE);
      }
      break;
	  
    case OMP.DATA_REDUCTION_MAX:
      if(id.Type().getKind() == Xtype.BASIC)
	bt = id.Type().getBasicType();
      else if(id.Type().isEnum()) bt = BasicType.INT;
      else bt = BasicType.UNDEF;
      switch(bt){
      case BasicType.CHAR:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),-128);
      case BasicType.SHORT:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),-32768);
      case BasicType.SIGNED:
      case BasicType.INT:
      case BasicType.LONG:
	  // return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),-2147483648);
	  // to avoid gcc warning
	  return Xcons.Int(Xcode.INT_CONSTANT,Xtype.unsignedType,0x80000000);
      case BasicType.UNSIGNED_CHAR:
      case BasicType.UNSIGNED_SHORT:
      case BasicType.UNSIGNED_INT:
      case BasicType.UNSIGNED_LONG:
	return Xcons.Int(Xcode.INT_CONSTANT,id.Type(),0);

      case BasicType.FLOAT:
	return Xcons.Float(Xcode.FLOAT_CONSTANT,id.Type(),-Float.MAX_VALUE);
      case BasicType.DOUBLE:
	return Xcons.Float(Xcode.FLOAT_CONSTANT,id.Type(),-Double.MAX_VALUE);
      }
      break;
    }
    OMP.fatal("OMPvar.reductionInitValue");
    return null;
  }
    
  /* obsolute!, not used any more */
  int reductionOpcode(){
    switch(reduction_op){
    case OMP.DATA_REDUCTION_PLUS:
      return Xcode.PLUS_EXPR;
    case OMP.DATA_REDUCTION_MINUS:
      return Xcode.MINUS_EXPR;
    case OMP.DATA_REDUCTION_MUL:
      return Xcode.MUL_EXPR;
    case OMP.DATA_REDUCTION_BITAND:
      return Xcode.BIT_AND_EXPR;
    case OMP.DATA_REDUCTION_BITOR:
      return Xcode.BIT_OR_EXPR;
    case OMP.DATA_REDUCTION_BITXOR:
      return Xcode.BIT_XOR_EXPR;
    case OMP.DATA_REDUCTION_LOGAND:
      return Xcode.LOG_AND_EXPR;
    case OMP.DATA_REDUCTION_LOGOR:
      return Xcode.LOG_OR_EXPR;
    case OMP.DATA_REDUCTION_MIN:
    case OMP.DATA_REDUCTION_MAX:
    }
    OMP.fatal("OMPvar.reductionOpcode");
    return 0;
  }
}


