<commit_before>/*
 * This file is released under terms of BSD license
 * See LICENSE file for more information
 */

package cx2x.translator.transformation;

// Cx2x import
import cx2x.xcodeml.helper.*;
import cx2x.xcodeml.xelement.*;
import cx2x.xcodeml.transformation.*;
import cx2x.xcodeml.exception.*;
import cx2x.translator.pragma.*;


// OMNI import
import xcodeml.util.XmOption;

// Java import
import java.util.*;
import java.util.regex.*;

/**
 * A LoopExtraction transformation is an independent transformation. The
 * transformation consists of locating a loop in a function call and extract it.
 * This loop is then wrapped around the function call and the parameters are
 * demoted accordingly to the mapping options.
 *
 * @author clementval
 */

public class LoopExtraction extends Transformation<LoopExtraction> {

  private XexprStatement _exprStmt = null;
  private List<ClawMapping> _mappings = null;
  private Map<String, ClawMapping> _mappingMap = null;
  private XfctCall _fctCall = null;
  private XfctDef _fctDef = null; // Fct holding the fct call
  private XfctDef _fctDefToExtract = null;
  private XdoStatement _extractedLoop = null;
  private XfctDef _copiedFctDef = null;

  // Fusion and fusion option
  private boolean _hasFusion = false;
  private String _fusionGroupLabel = "";

  // Acc options
  private boolean _hasParallelOption = false;
  private String _accAdditionalOption = null;

  /**
   * Constructs a new LoopExtraction triggered from a specific pragma.
   * @param pragma  The pragma that triggered the loop extraction
   *                transformation.
   */
  public LoopExtraction(Xpragma pragma) throws IllegalDirectiveException {
    super(pragma);
    _mappings = new ArrayList<>();
    _mappingMap = new Hashtable<>();
    extractRangeInformation();
    extractFusionInformation();

    _hasParallelOption = ClawPragma.hasParallelOption(pragma.getData());
    _accAdditionalOption = ClawPragma.getAccOptionValue(pragma.getData());

    try {
      extractMappingInformation();
    } catch (IllegalDirectiveException ide){
      ide.setDirectiveLine(_pragma.getLine());
      throw ide;
    }
  }

  private void extractRangeInformation(){
    // TODO
  }

  /**
   * Extract all mapping information from the pragma data. Each
   * map(<mapped>:<mapping>) produces a ClawMapping object.
   */
  private void extractMappingInformation() throws IllegalDirectiveException {
    _mappings = ClawPragma.extractMappingInformation(_pragma.getData());
    for(ClawMapping m : _mappings){
      for(String mappedVar : m.getMappedVariables()){
        _mappingMap.put(mappedVar, m);
      }
    }
  }

  /**
   * Extract optional fusion information. The extract loop might later be merged
   * with a fusion group. This method extract whether there is a fusion to
   * perform and its optional fusion group option.
   */
  private void extractFusionInformation(){
    _hasFusion = ClawPragma.hasFusionOption(_pragma.getData());
    _fusionGroupLabel = ClawPragma.getExtractFusionOption(_pragma.getData());
  }

  /**
   * Check whether the provided mapping information are correct or not. A
   * mapped variable should only appear once. Mapped variable must be parameters
   * in the function definition.
   * Mapping using the same mapping variables are merged together.
   * @return True if all the conditions are respected. False otherwise.
   */
  private boolean checkMappingInformation(){
    // TODO Mapped variable should appear on one time
    // TODO Mapped variable should be declared in the fct definition
    // declarations or in the global declarations table

    // TODO Merge mapping if they have the exact same mapping vars to reduce the
    // number of iteration for the demotions

    return true; // TODO
  }

  /**
   *
   * @param xcodeml      The XcodeML on which the transformations are applied.
   * @param transformer  The transformer used to applied the transformations.
   * @return True if the transformation analysis succeeded. False otherwise.
   */
  public boolean analyze(XcodeProg xcodeml, Transformer transformer){
    _exprStmt = XelementHelper.findNextExprStatement(_pragma);
    if(_exprStmt == null){
      xcodeml.addError("No function call detected after loop-extract",
        _pragma.getLine());
      return false;
    }

    // Find function CALL
    _fctCall = XelementHelper.findFctCall(_exprStmt);
    if(_fctCall == null){
      xcodeml.addError("No function call detected after loop-extract",
        _pragma.getLine());
      return false;
    }

    _fctDef = XelementHelper.findParentFctDef(_fctCall);
    if(_fctDef == null){
      xcodeml.addError("No function around the fct call",
        _pragma.getLine());
      return false;
    }

    // Find function declaration
    _fctDefToExtract = XelementHelper.findFunctionDefinition(xcodeml, _fctCall);

    if(_fctDefToExtract == null){
      System.err.println("Could not locate the function definition for: "
        + _fctCall.getFctName());
      System.exit(1);
    }
<commit_msg>Check that mapped variable appears only once<commit_after>/*
 * This file is released under terms of BSD license
 * See LICENSE file for more information
 */

package cx2x.translator.transformation;

// Cx2x import
import cx2x.xcodeml.helper.*;
import cx2x.xcodeml.xelement.*;
import cx2x.xcodeml.transformation.*;
import cx2x.xcodeml.exception.*;
import cx2x.translator.pragma.*;

// OMNI import
import xcodeml.util.XmOption;

// Java import
import java.util.*;

/**
 * A LoopExtraction transformation is an independent transformation. The
 * transformation consists of locating a loop in a function call and extract it.
 * This loop is then wrapped around the function call and the parameters are
 * demoted accordingly to the mapping options.
 *
 * @author clementval
 */

public class LoopExtraction extends Transformation<LoopExtraction> {

  private List<ClawMapping> _mappings = null;
  private Map<String, ClawMapping> _mappingMap = null;
  private XfctCall _fctCall = null;
  private XfctDef _fctDef = null; // Fct holding the fct call
  private XfctDef _fctDefToExtract = null;
  private XdoStatement _extractedLoop = null;

  // Fusion and fusion option
  private boolean _hasFusion = false;
  private String _fusionGroupLabel = "";

  // Acc options
  private boolean _hasParallelOption = false;
  private String _accAdditionalOption = null;

  /**
   * Constructs a new LoopExtraction triggered from a specific pragma.
   * @param pragma  The pragma that triggered the loop extraction
   *                transformation.
   */
  public LoopExtraction(Xpragma pragma) throws IllegalDirectiveException {
    super(pragma);
    _mappings = new ArrayList<>();
    _mappingMap = new Hashtable<>();
    extractRangeInformation();
    extractFusionInformation();

    _hasParallelOption = ClawPragma.hasParallelOption(pragma.getData());
    _accAdditionalOption = ClawPragma.getAccOptionValue(pragma.getData());

    try {
      extractMappingInformation();
    } catch (IllegalDirectiveException ide){
      ide.setDirectiveLine(_pragma.getLine());
      throw ide;
    }
  }

  private void extractRangeInformation(){
    // TODO
  }

  /**
   * Extract all mapping information from the pragma data. Each
   * map(<mapped>:<mapping>) produces a ClawMapping object.
   */
  private void extractMappingInformation() throws IllegalDirectiveException {
    _mappings = ClawPragma.extractMappingInformation(_pragma.getData());
    for(ClawMapping m : _mappings){
      for(String mappedVar : m.getMappedVariables()){
        if(_mappingMap.containsKey(mappedVar)){
          throw new IllegalDirectiveException(_pragma.getData(), mappedVar +
              " appears more than once in the mapping");
        } else {
          _mappingMap.put(mappedVar, m);
        }
      }
    }
  }

  /**
   * Extract optional fusion information. The extract loop might later be merged
   * with a fusion group. This method extract whether there is a fusion to
   * perform and its optional fusion group option.
   */
  private void extractFusionInformation(){
    _hasFusion = ClawPragma.hasFusionOption(_pragma.getData());
    _fusionGroupLabel = ClawPragma.getExtractFusionOption(_pragma.getData());
  }

  /**
   * Check whether the provided mapping information are correct or not. A
   * mapped variable should only appear once. Mapped variable must be parameters
   * in the function definition.
   * Mapping using the same mapping variables are merged together.
   * @return True if all the conditions are respected. False otherwise.
   */
  private boolean checkMappingInformation(){
    // TODO Mapped variable should be declared in the fct definition
    // declarations or in the global declarations table

    // TODO Merge mapping if they have the exact same mapping vars to reduce the
    // number of iteration for the demotions

    return true; // TODO
  }

  /**
   *
   * @param xcodeml      The XcodeML on which the transformations are applied.
   * @param transformer  The transformer used to applied the transformations.
   * @return True if the transformation analysis succeeded. False otherwise.
   */
  public boolean analyze(XcodeProg xcodeml, Transformer transformer){
    XexprStatement _exprStmt = XelementHelper.findNextExprStatement(_pragma);
    if(_exprStmt == null){
      xcodeml.addError("No function call detected after loop-extract",
        _pragma.getLine());
      return false;
    }

    // Find function CALL
    _fctCall = XelementHelper.findFctCall(_exprStmt);
    if(_fctCall == null){
      xcodeml.addError("No function call detected after loop-extract",
        _pragma.getLine());
      return false;
    }

    _fctDef = XelementHelper.findParentFctDef(_fctCall);
    if(_fctDef == null){
      xcodeml.addError("No function around the fct call",
        _pragma.getLine());
      return false;
    }

    // Find function declaration
    _fctDefToExtract = XelementHelper.findFunctionDefinition(xcodeml, _fctCall);

    if(_fctDefToExtract == null){
      System.err.println("Could not locate the function definition for: "
        + _fctCall.getFctName());
      System.exit(1);
    }

{'fraction_non_alphanumeric': 0.08263649778652238, 'fraction_numerical': 0.001574028529267093, 'mean_word_length': 3.4725032996040475, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '257249', 'n_tokens_mistral': 2846, 'n_tokens_neox': 2766, 'n_words': 904}