<commit_before>/*
 * This file is part of libFirm.
 * Copyright (C) 2012 University of Karlsruhe.
 */

/**
 * @file
 * @brief   Reassociation
 * @author  <NAME>
 */
#include "iroptimize.h"
#include "iropt_t.h"
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "ircons_t.h"
#include "irgmod.h"
#include "irgopt.h"
#include "iropt_dbg.h"
#include "irflag_t.h"
#include "irgwalk.h"
#include "irouts.h"
#include "reassoc_t.h"
#include "opt_init.h"
#include "irhooks.h"
#include "irloop.h"
#include "pdeq.h"
#include "debug.h"

DEBUG_ONLY(static firm_dbg_module_t *dbg;)

typedef enum {
	NO_CONSTANT,   /**< node is not constant */
	REAL_CONSTANT, /**< a Const that is suitable for constant folding */
	REGION_CONST   /**< a constant expression in the current context */
} const_class_t;

/**
 * returns whether a node is constant ie is a constant or
 * is loop invariant (called region constant)
 *
 * @param n     the node to be checked for constant
 * @param block a block that might be in a loop
 */
static const_class_t get_const_class(const ir_node *n, const ir_node *block)
{
	if (is_Const(n))
		return REAL_CONSTANT;

	/* constant nodes which can't be folded are region constants */
	if (is_irn_constlike(n))
		return REGION_CONST;

	/*
	 * Beware: Bad nodes are always loop-invariant, but
	 * cannot handled in later code, so filter them here.
	 */
	if (!is_Bad(n) && is_loop_invariant(n, block))
		return REGION_CONST;

	return NO_CONSTANT;
}

/**
 * returns the operands of a commutative bin-op, if one operand is
 * a region constant, it is returned as the second one.
 *
 * Beware: Real constants must be returned with higher priority than
 * region constants, because they might be folded.
 */
static void get_comm_Binop_ops(ir_node *binop, ir_node **a, ir_node **c)
{
	assert(is_op_commutative(get_irn_op(binop)));
	ir_node *op_a = get_binop_left(binop);
	ir_node *op_b = get_binop_right(binop);
	ir_node *block = get_nodes_block(binop);
	int class_a = get_const_class(op_a, block);
	int class_b = get_const_class(op_b, block);

	if (class_a == REAL_CONSTANT && class_b == REAL_CONSTANT) {
		/* if both are constants, one might be a
		 * pointer constant like NULL, return the other */
		if (mode_is_reference(get_irn_mode(op_a))) {
			*a = op_a;
			*c = op_b;
		} else {
			*a = op_b;
			*c = op_a;
		}
	} else if (class_a == REAL_CONSTANT
	           || (class_a == REGION_CONST && class_b == NO_CONSTANT)) {
		*a = op_b;
		*c = op_a;
	} else {
		*a = op_a;
		*c = op_b;
	}
}<commit_msg>Fixed type.<commit_after>/*
 * This file is part of libFirm.
 * Copyright (C) 2012 University of Karlsruhe.
 */

/**
 * @file
 * @brief   Reassociation
 * @author  <NAME>
 */
#include "iroptimize.h"
#include "iropt_t.h"
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "ircons_t.h"
#include "irgmod.h"
#include "irgopt.h"
#include "iropt_dbg.h"
#include "irflag_t.h"
#include "irgwalk.h"
#include "irouts.h"
#include "reassoc_t.h"
#include "opt_init.h"
#include "irhooks.h"
#include "irloop.h"
#include "pdeq.h"
#include "debug.h"

DEBUG_ONLY(static firm_dbg_module_t *dbg;)

typedef enum {
	NO_CONSTANT,   /**< node is not constant */
	REAL_CONSTANT, /**< a Const that is suitable for constant folding */
	REGION_CONST   /**< a constant expression in the current context */
} const_class_t;

/**
 * returns whether a node is constant ie is a constant or
 * is loop invariant (called region constant)
 *
 * @param n     the node to be checked for constant
 * @param block a block that might be in a loop
 */
static const_class_t get_const_class(const ir_node *n, const ir_node *block)
{
	if (is_Const(n))
		return REAL_CONSTANT;

	/* constant nodes which can't be folded are region constants */
	if (is_irn_constlike(n))
		return REGION_CONST;

	/*
	 * Beware: Bad nodes are always loop-invariant, but
	 * cannot handled in later code, so filter them here.
	 */
	if (!is_Bad(n) && is_loop_invariant(n, block))
		return REGION_CONST;

	return NO_CONSTANT;
}

/**
 * returns the operands of a commutative bin-op, if one operand is
 * a region constant, it is returned as the second one.
 *
 * Beware: Real constants must be returned with higher priority than
 * region constants, because they might be folded.
 */
static void get_comm_Binop_ops(ir_node *binop, ir_node **a, ir_node **c)
{
	assert(is_op_commutative(get_irn_op(binop)));
	ir_node       *op_a    = get_binop_left(binop);
	ir_node       *op_b    = get_binop_right(binop);
	ir_node       *block   = get_nodes_block(binop);
	const_class_t  class_a = get_const_class(op_a, block);
	const_class_t  class_b = get_const_class(op_b, block);

	if (class_a == REAL_CONSTANT && class_b == REAL_CONSTANT) {
		/* if both are constants, one might be a
		 * pointer constant like NULL, return the other */
		if (mode_is_reference(get_irn_mode(op_a))) {
			*a = op_a;
			*c = op_b;
		} else {
			*a = op_b;
			*c = op_a;
		}
	} else if (class_a == REAL_CONSTANT
	           || (class_a == REGION_CONST && class_b == NO_CONSTANT)) {
		*a = op_b;
		*c = op_a;
	} else {
		*a = op_a;
		*c = op_b;
	}
}
{'fraction_non_alphanumeric': 0.12303767660910518, 'fraction_numerical': 0.0015698587127158557, 'mean_word_length': 3.8404558404558404, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, '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': '2707753', 'n_tokens_mistral': 1996, 'n_tokens_neox': 1908, 'n_words': 561}