<commit_before>/*
 * Project:     libFIRM
 * File name:   ir/opt/ifconv.c
 * Purpose:     If conversion
 * Author:      <NAME>.
 * Created:
 * CVS-ID:      $Id$
 * Copyright:   (c) 1998-2005 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */

#if 1

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif

#include <assert.h>

#include "obst.h"
#include "irnode_t.h"
#include "cdep.h"
#include "ircons.h"
#include "ifconv.h"
#include "irdom.h"
#include "irgmod.h"
#include "irgopt.h"
#include "irgwalk.h"
#include "irtools.h"
#include "return.h"
#include "array.h"

// debug
#include "irdump.h"
#include "debug.h"

DEBUG_ONLY(firm_dbg_module_t *dbg);


/**
 * Additional block info.
 */
typedef struct block_info {
	ir_node *phi;   /**< head of the Phi list */
	int has_pinned; /**< set if the block contains instructions that cannot be moved */
} block_info;

#define get_block_blockinfo(block) ((block_info *)get_irn_link(block))

/**
 * Returns non-zero if a Block can be emptied.
 */
static int can_empty_block(ir_node *block)
{
	return !get_block_blockinfo(block)->has_pinned;
}


static ir_node* walk_to_projx(ir_node* start, const ir_node* dependency)
{
	int arity;
	int i;

	/* No need to find the conditional block if this block cannot be emptied and
	 * therefore not moved
	 */
	if (!can_empty_block(start)) return NULL;

	arity = get_irn_arity(start);
	for (i = 0; i < arity; ++i) {
		ir_node* pred = get_irn_n(start, i);
		ir_node* pred_block = get_nodes_block(pred);

		if (pred_block == dependency) {
			assert(is_Proj(pred));
			assert(get_irn_mode(pred) == mode_X);
			return pred;
		}

		if (is_Proj(pred)) {
			assert(get_irn_mode(pred) == mode_X);
			return NULL;
		}

		if (is_cdep_on(pred_block, dependency)) {
			return walk_to_projx(pred_block, dependency);
		}
	}<commit_msg>BugFix: Predecessors of blocks can be even Jmp and Raise nodes if exceptions are used, handle this<commit_after>/*
 * Project:     libFIRM
 * File name:   ir/opt/ifconv.c
 * Purpose:     If conversion
 * Author:      <NAME>.
 * Created:
 * CVS-ID:      $Id$
 * Copyright:   (c) 1998-2005 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */

#if 1

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif

#include <assert.h>

#include "obst.h"
#include "irnode_t.h"
#include "cdep.h"
#include "ircons.h"
#include "ifconv.h"
#include "irdom.h"
#include "irgmod.h"
#include "irgopt.h"
#include "irgwalk.h"
#include "irtools.h"
#include "return.h"
#include "array.h"

// debug
#include "irdump.h"
#include "debug.h"

DEBUG_ONLY(firm_dbg_module_t *dbg);


/**
 * Additional block info.
 */
typedef struct block_info {
	ir_node *phi;   /**< head of the Phi list */
	int has_pinned; /**< set if the block contains instructions that cannot be moved */
} block_info;

#define get_block_blockinfo(block) ((block_info *)get_irn_link(block))

/**
 * Returns non-zero if a Block can be emptied.
 */
static int can_empty_block(ir_node *block)
{
	return !get_block_blockinfo(block)->has_pinned;
}


static ir_node* walk_to_projx(ir_node* start, const ir_node* dependency)
{
	int arity;
	int i;

	/* No need to find the conditional block if this block cannot be emptied and
	 * therefore not moved
	 */
	if (!can_empty_block(start)) return NULL;

	arity = get_irn_arity(start);
	for (i = 0; i < arity; ++i) {
		ir_node* pred = get_irn_n(start, i);
		ir_node* pred_block = get_nodes_block(pred);

		if (pred_block == dependency) {
			if (is_Proj(pred)) {
				assert(get_irn_mode(pred) == mode_X);
				return pred;
			}
			return NULL;
		}

		if (is_Proj(pred)) {
			assert(get_irn_mode(pred) == mode_X);
			return NULL;
		}

		if (is_cdep_on(pred_block, dependency)) {
			return walk_to_projx(pred_block, dependency);
		}
	}
{'fraction_non_alphanumeric': 0.13417085427135678, 'fraction_numerical': 0.005025125628140704, 'mean_word_length': 3.97625, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 13, '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': '713953', 'n_tokens_mistral': 1624, 'n_tokens_neox': 1515, 'n_words': 403}