<commit_before>#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>

#include "../../util/alloc.h"
#include "../../util/dynarray.h"

#include "../type.h"
#include "../num.h"
#include "../str.h" /* str_add_escape */

#include "val.h"
#include "ctx.h"
#include "out.h" /* out_blk_new() */
#include "lbl.h"
#include "dbg.h"

#include "blk.h"
#include "impl_jmp.h"

#include "asm.h" /* cc_out */
#include "../cc1.h" /* fopt_mode */

#define JMP_THREAD_LIM 10

struct flush_state
{
	FILE *f;

	/* for jump threading - the block we jump to if not immediately flushing */
	out_blk *jmpto;
};

static void blk_jmpnext(out_blk *to, struct flush_state *st)
{
	assert(!st->jmpto);
	st->jmpto = to;
}

static void blk_jmpthread(struct flush_state *st)
{
	int lim = 0;
	out_blk *to = st->jmpto;

	while(!to->insns && to->type == BLK_NEXT_BLOCK && lim < JMP_THREAD_LIM){
			to = to->bits.next;
			lim++; /* prevent circulars */
	}

	if(lim && fopt_mode & FOPT_VERBOSE_ASM)
		fprintf(st->f, "\t# jump threaded through %d blocks\n", lim);

	impl_jmp(st->f, to->lbl);
}

static void blk_codegen(out_blk *blk, struct flush_state *st)
{
	char **i;

	/* before any instructions, if we have a pending jmpto and
	 * we aren't the target branch, we need to cut off the last
	 * block with a jump to said jmpto */
	if(st->jmpto){
		if(st->jmpto != blk)
			blk_jmpthread(st);
		else if(fopt_mode & FOPT_VERBOSE_ASM)
			fprintf(st->f, "\t# implicit jump to next line\n");
		st->jmpto = NULL;
	}

	fprintf(st->f, "%s: # %s\n", blk->lbl, blk->desc);

	for(i = blk->insns; i && *i; i++)
		fprintf(st->f, "%s", *i);
}

static void bfs_block(out_blk *blk, struct flush_state *st, int const force)
{
	if(blk->flush_in_prog)
		return;
	blk->flush_in_prog = 1;

	/* dead code elimination: */
	if(!force && !blk->merge_preds)
		return;

	if(blk->merge_preds){
		out_blk **i;

		for(i = blk->merge_preds; *i; i++){
			bfs_block(*i, st, 0);
		}
	}<commit_msg>Explain dead-code-elimination condition<commit_after>#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>

#include "../../util/alloc.h"
#include "../../util/dynarray.h"

#include "../type.h"
#include "../num.h"
#include "../str.h" /* str_add_escape */

#include "val.h"
#include "ctx.h"
#include "out.h" /* out_blk_new() */
#include "lbl.h"
#include "dbg.h"

#include "blk.h"
#include "impl_jmp.h"

#include "asm.h" /* cc_out */
#include "../cc1.h" /* fopt_mode */

#define JMP_THREAD_LIM 10

struct flush_state
{
	FILE *f;

	/* for jump threading - the block we jump to if not immediately flushing */
	out_blk *jmpto;
};

static void blk_jmpnext(out_blk *to, struct flush_state *st)
{
	assert(!st->jmpto);
	st->jmpto = to;
}

static void blk_jmpthread(struct flush_state *st)
{
	int lim = 0;
	out_blk *to = st->jmpto;

	while(!to->insns && to->type == BLK_NEXT_BLOCK && lim < JMP_THREAD_LIM){
			to = to->bits.next;
			lim++; /* prevent circulars */
	}

	if(lim && fopt_mode & FOPT_VERBOSE_ASM)
		fprintf(st->f, "\t# jump threaded through %d blocks\n", lim);

	impl_jmp(st->f, to->lbl);
}

static void blk_codegen(out_blk *blk, struct flush_state *st)
{
	char **i;

	/* before any instructions, if we have a pending jmpto and
	 * we aren't the target branch, we need to cut off the last
	 * block with a jump to said jmpto */
	if(st->jmpto){
		if(st->jmpto != blk)
			blk_jmpthread(st);
		else if(fopt_mode & FOPT_VERBOSE_ASM)
			fprintf(st->f, "\t# implicit jump to next line\n");
		st->jmpto = NULL;
	}

	fprintf(st->f, "%s: # %s\n", blk->lbl, blk->desc);

	for(i = blk->insns; i && *i; i++)
		fprintf(st->f, "%s", *i);
}

static void bfs_block(out_blk *blk, struct flush_state *st, int const force)
{
	if(blk->flush_in_prog)
		return;
	blk->flush_in_prog = 1;

	/* dead code elimination: */
	if(!force && !blk->merge_preds){
		/* should only do this if called back from the merge-pred loop below,
		 * since otherwise we're called from a BLK_NEXT_BLOCK, which means
		 * control does jump into us */
		return;
	}

	if(blk->merge_preds){
		out_blk **i;

		for(i = blk->merge_preds; *i; i++){
			bfs_block(*i, st, 0);
		}
	}
{'fraction_non_alphanumeric': 0.18208162279642598, 'fraction_numerical': 0.0028978507606858247, 'mean_word_length': 3.581858407079646, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 59, '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': '4693837', 'n_tokens_mistral': 1787, 'n_tokens_neox': 1705, 'n_words': 436}