// $Id: shmcc.java,v 1.9 2002/01/14 09:14:24 a-hasega 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 shm;

import exc.object.*;
import exc.openmp.*;
import exc.tea.*;

public class shmcc extends exc.util.ccDriver {
  protected boolean relocateGlobalFlag = true;

  public shmcc(){ super("shmcc"); }

  public static void main(String args[]){ 
    shmcc driver = new shmcc();
    driver.run(args);
  }

  public boolean parseArg(String arg){
    if(arg.equals("--no-relocate")){
      relocateGlobalFlag = false;
      if(verbose) System.err.println("relocate flag off...");
      return true;
    } else return false;
  }

  public void init(){
    cpp_opts += " -DOMPC";
    if (getTemplateValue("APPROVED_DATE") != null) {
      cpp_opts += " -D_OPENMP=" + getTemplateValue("APPROVED_DATE");
    } else {
      cpp_opts += " -D_OPENMP";
    }
    if(getTemplateValue("CFRONT_FLAGS") != null) 
      cpp_opts += " "+getTemplateValue("CFRONT_FLAGS");
    cpp_opts += " "+getTemplateValue("OMPC_CFLAGS");
    // cc_opts += " "+getTemplateValue("OMPC_CFLAGS");

    ld_opts += " "+getTemplateValue("OMPC_MAIN");
    ld_opts += " "+getTemplateValue("OMPC_LDFLAGS");
  }

  public void run(XobjectFile f){
    if(verbose) System.err.println("transformation pass ... "+
				   f.getSourceFileName());
    f.debugFlag = debugFlag;
    OMP.debugFlag = debugFlag;

    OMP.setMoveAutoFlag(true);
    OMP.leaveThreadPrivate(true);

    TEAanalyzeDecl opTEA = new TEAanalyzeDecl();
    opTEA.init(f);

    OMPtranslateBlock op = new OMPtranslateBlock();
    op.init(f,false);

    f.iterateDef(opTEA);
    f.iterateDef(op);   // transform OMP pragma
    if(OMP.errorFlags){
      System.err.println("error in OpenMP. stop.");
      System.exit(1);
    }

    if(relocateGlobalFlag){
      if(verbose) System.err.println("relocate global data pass ...");
      // relocate global data to shared memory area
      relocateGlobalData opRel = new relocateGlobalData();
      opRel.init(f);
      f.iterateDef(opRel);
      opRel.Finalize();
    }

    op.init(f,true);
    if(verbose) System.err.println("block transformation data ...");
    f.iterateDef(op);   // transform OMP pragma

    f.addTailerLine("static char *__g_data_init_f=(char *)__G_DATA_INIT; ");
    f.addTailerLine("static void __G_DATA_CTOR() {");
    f.addTailerLine("  asm(\".section	.ctors \");");
    f.addTailerLine("  asm(\".long	 __G_DATA_INIT\");");
    f.addTailerLine("  asm(\".section	.text \");");
    f.addTailerLine("}");
    f.addTailerLine("static char *__g_data_ctor_f=(char *)__G_DATA_CTOR; ");
  }
}

