/*
 * Copyright (C) 2009 Nicolai Haehnle.
 *
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include "radeon_program_pair.h"

#include <stdio.h>

#include "radeon_compiler.h"
#include "radeon_compiler_util.h"
#include "radeon_dataflow.h"
#include "radeon_list.h"
#include "radeon_variable.h"

#include "util/u_debug.h"

#define VERBOSE 0

#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)

struct schedule_instruction {
	struct rc_instruction * Instruction;

	/** Next instruction in the linked list of ready instructions. */
	struct schedule_instruction *NextReady;

	/** Values that this instruction reads and writes */
	struct reg_value * WriteValues[4];
	struct reg_value * ReadValues[12];
	unsigned int NumWriteValues:3;
	unsigned int NumReadValues:4;

	/**
	 * Number of (read and write) dependencies that must be resolved before
	 * this instruction can be scheduled.
	 */
	unsigned int NumDependencies:5;

	/** List of all readers (see rc_get_readers() for the definition of
	 * "all readers"), even those outside the basic block this instruction
	 * lives in. */
	struct rc_reader_data GlobalReaders;

	/** If the scheduler has paired an RGB and an Alpha instruction together,
	 * PairedInst references the alpha insturction's dependency information.
	 */
	struct schedule_instruction * PairedInst;

	/** This scheduler uses the value of Score to determine which
	 * instruction to schedule.  Instructions with a higher value of Score
	 * will be scheduled first. */
	int Score;

	/** The number of components that read from a TEX instruction. */
	unsigned TexReadCount;

	/** For TEX instructions a list of readers */
	struct rc_list * TexReaders;
};


/**
 * Used to keep track of which instructions read a value.
 */
struct reg_value_reader {
	struct schedule_instruction *Reader;
	struct reg_value_reader *Next;
};

/**
 * Used to keep track which values are stored in each component of a
 * RC_FILE_TEMPORARY.
 */
struct reg_value {
	struct schedule_instruction * Writer;

	/**
	 * Unordered linked list of instructions that read from this value.
	 * When this value becomes available, we increase all readers'
	 * dependency count.
	 */
	struct reg_value_reader *Readers;

	/**
	 * Number of readers of this value. This is decremented each time
	 * a reader of the value is committed.
	 * When the reader cound reaches zero, the dependency count
	 * of the instruction writing \ref Next is decremented.
	 */
	unsigned int NumReaders;

	struct reg_value *Next; /**< Pointer to the next value to be written to the same register */
};

struct register_state {
	struct reg_value * Values[4];
};

struct remap_reg {
	struct rc_instruciont * Inst;
	unsigned int OldIndex:(RC_REGISTER_INDEX_BITS+1);
	unsigned int OldSwizzle:3;
	unsigned int NewIndex:(RC_REGISTER_INDEX_BITS+1);
	unsigned int NewSwizzle:3;
	unsigned int OnlyTexReads:1;
	struct remap_reg * Next;
};

struct schedule_state {
	struct radeon_compiler * C;
	struct schedule_instruction * Current;
	/** Array of the previous writers of Current's destination register
	 * indexed by channel. */
	struct schedule_instruction * PrevWriter[4];

	struct register_state Temporary[RC_REGISTER_MAX_INDEX];

	/**
	 * Linked lists of instructions that can be scheduled right now,
	 * based on which ALU/TEX resources they require.
	 */
	/*@{*/
	struct schedule_instruction *ReadyFullALU;
	struct schedule_instruction *ReadyRGB;
	struct schedule_instruction *ReadyAlpha;
	struct schedule_instruction *ReadyTEX;
	/*@}*/
	struct rc_list *PendingTEX;

	void (*CalcScore)(struct schedule_instruction *);
	long max_tex_group;
	unsigned PrevBlockHasTex:1;
	unsigned TEXCount;
	unsigned Opt:1;
};

static struct reg_value ** get_reg_valuep(struct schedule_state * s,
		rc_register_file file, unsigned int index, unsigned int chan)
{
	if (file != RC_FILE_TEMPORARY)
		return 0;

	if (index >= RC_REGISTER_MAX_INDEX) {
		rc_error(s->C, "%s: index %i out of bounds\n", __FUNCTION__, index);
		return 0;
	}

	return &s->Temporary[index].Values[chan];
}

static unsigned get_tex_read_count(struct schedule_instruction * sinst)
{
	unsigned tex_read_count = sinst->TexReadCount;
	if (sinst->PairedInst) {
		tex_read_count += sinst->PairedInst->TexReadCount;
	}
	return tex_read_count;
}

#if VERBOSE
static void print_list(struct schedule_instruction * sinst)
{
	struct schedule_instruction * ptr;
	for (ptr = sinst; ptr; ptr=ptr->NextReady) {
		unsigned tex_read_count = get_tex_read_count(ptr);
		unsigned score = sinst->Score;
		fprintf(stderr,"%u (%d) [%u],", ptr->Instruction->IP, score,
						tex_read_count);
	}
	fprintf(stderr, "\n");
}
#endif

static void remove_inst_from_list(struct schedule_instruction ** list,
					struct schedule_instruction * inst)
{
	struct schedule_instruction * prev = NULL;
	struct schedule_instruction * list_ptr;
	for (list_ptr = *list; list_ptr; prev = list_ptr,
					list_ptr = list_ptr->NextReady) {
		if (list_ptr == inst) {
			if (prev) {
				prev->NextReady = inst->NextReady;
			} else {
				*list = inst->NextReady;
			}
			inst->NextReady = NULL;
			break;
		}
	}
}

static void add_inst_to_list(struct schedule_instruction ** list, struct schedule_instruction * inst)
{
	inst->NextReady = *list;
	*list = inst;
}

static void add_inst_to_list_score(struct schedule_instruction ** list,
					struct schedule_instruction * inst)
{
	struct schedule_instruction * temp;
	struct schedule_instruction * prev;
	if (!*list) {
		*list = inst;
		return;
	}
	temp = *list;
	prev = NULL;
	while(temp && inst->Score <= temp->Score) {
		prev = temp;
		temp = temp->NextReady;
	}

	if (!prev) {
		inst->NextReady = temp;
		*list = inst;
	} else {
		prev->NextReady = inst;
		inst->NextReady = temp;
	}
}

static void instruction_ready(struct schedule_state * s, struct schedule_instruction * sinst)
{
	DBG("%i is now ready\n", sinst->Instruction->IP);

	/* Adding Ready TEX instructions to the end of the "Ready List" helps
	 * us emit TEX instructions in blocks without losing our place. */
	if (sinst->Instruction->Type == RC_INSTRUCTION_NORMAL)
		add_inst_to_list_score(&s->ReadyTEX, sinst);
	else if (sinst->Instruction->U.P.Alpha.Opcode == RC_OPCODE_NOP)
		add_inst_to_list_score(&s->ReadyRGB, sinst);
	else if (sinst->Instruction->U.P.RGB.Opcode == RC_OPCODE_NOP)
		add_inst_to_list_score(&s->ReadyAlpha, sinst);
	else
		add_inst_to_list_score(&s->ReadyFullALU, sinst);
}

static void decrease_dependencies(struct schedule_state * s, struct schedule_instruction * sinst)
{
	assert(sinst->NumDependencies > 0);
	sinst->NumDependencies--;
	if (!sinst->NumDependencies)
		instruction_ready(s, sinst);
}

/* These functions provide different heuristics for scheduling instructions.
 * The default is calc_score_readers. */

#if 0

static void calc_score_zero(struct schedule_instruction * sinst)
{
	sinst->Score = 0;
}

static void calc_score_deps(struct schedule_instruction * sinst)
{
	int i;
	sinst->Score = 0;
	for (i = 0; i < sinst->NumWriteValues; i++) {
		struct reg_value * v = sinst->WriteValues[i];
		if (v->NumReaders) {
			struct reg_value_reader * r;
			for (r = v->Readers; r; r = r->Next) {
				if (r->Reader->NumDependencies == 1) {
					sinst->Score += 100;
				}
				sinst->Score += r->Reader->NumDependencies;
			}
		}
	}
}

#endif

#define NO_OUTPUT_SCORE (1 << 24)

static void score_no_output(struct schedule_instruction * sinst)
{
	assert(sinst->Instruction->Type != RC_INSTRUCTION_NORMAL);
	if (!sinst->Instruction->U.P.RGB.OutputWriteMask &&
			!sinst->Instruction->U.P.Alpha.OutputWriteMask) {
		if (sinst->PairedInst) {
			if (!sinst->PairedInst->Instruction->U.P.
							RGB.OutputWriteMask
					&& !sinst->PairedInst->Instruction->U.P.
							Alpha.OutputWriteMask) {
				sinst->Score |= NO_OUTPUT_SCORE;
			}

		} else {
			sinst->Score |= NO_OUTPUT_SCORE;
		}
	}
}

#define PAIRED_SCORE (1 << 16)

static void calc_score_r300(struct schedule_instruction * sinst)
{
	unsigned src_idx;

	if (sinst->Instruction->Type == RC_INSTRUCTION_NORMAL) {
		sinst->Score = 0;
		return;
	}

	score_no_output(sinst);

	if (sinst->PairedInst) {
		sinst->Score |= PAIRED_SCORE;
		return;
	}

	for (src_idx = 0; src_idx < 4; src_idx++) {
		sinst->Score += sinst->Instruction->U.P.RGB.Src[src_idx].Used +
				sinst->Instruction->U.P.Alpha.Src[src_idx].Used;
	}
}

#define NO_READ_TEX_SCORE (1 << 16)

static void calc_score_readers(struct schedule_instruction * sinst)
{
	if (sinst->Instruction->Type == RC_INSTRUCTION_NORMAL) {
		sinst->Score = 0;
	} else {
		sinst->Score = sinst->NumReadValues;
		if (sinst->PairedInst) {
			sinst->Score += sinst->PairedInst->NumReadValues;
		}
		if (get_tex_read_count(sinst) == 0) {
			sinst->Score |= NO_READ_TEX_SCORE;
		}
		score_no_output(sinst);
	}
}

/**
 * This function decreases the dependencies of the next instruction that
 * wants to write to each of sinst's read values.
 */
static void commit_update_reads(struct schedule_state * s,
					struct schedule_instruction * sinst){
	unsigned int i;
	for(i = 0; i < sinst->NumReadValues; ++i) {
		struct reg_value * v = sinst->ReadValues[i];
		assert(v->NumReaders > 0);
		v->NumReaders--;
		if (!v->NumReaders) {
			if (v->Next) {
				decrease_dependencies(s, v->Next->Writer);
			}
		}
	}
	if (sinst->PairedInst) {
		commit_update_reads(s, sinst->PairedInst);
	}
}

static void commit_update_writes(struct schedule_state * s,
					struct schedule_instruction * sinst){
	unsigned int i;
	for(i = 0; i < sinst->NumWriteValues; ++i) {
		struct reg_value * v = sinst->WriteValues[i];
		if (v->NumReaders) {
			for(struct reg_value_reader * r = v->Readers; r; r = r->Next) {
				decrease_dependencies(s, r->Reader);
			}
		} else {
			/* This happens in instruction sequences of the type
			 *  OP r.x, ...;
			 *  OP r.x, r.x, ...;
			 * See also the subtlety in how instructions that both
			 * read and write the same register are scanned.
			 */
			if (v->Next)
				decrease_dependencies(s, v->Next->Writer);
		}
	}
	if (sinst->PairedInst) {
		commit_update_writes(s, sinst->PairedInst);
	}
}

static void notify_sem_wait(struct schedule_state *s)
{
	struct rc_list * pend_ptr;
	for (pend_ptr = s->PendingTEX; pend_ptr; pend_ptr = pend_ptr->Next) {
		struct rc_list * read_ptr;
		struct schedule_instruction * pending = pend_ptr->Item;
		for (read_ptr = pending->TexReaders; read_ptr;
						read_ptr = read_ptr->Next) {
			struct schedule_instruction * reader = read_ptr->Item;
			reader->TexReadCount--;
		}
	}
	s->PendingTEX = NULL;
}

static void commit_alu_instruction(struct schedule_state * s, struct schedule_instruction * sinst)
{
	DBG("%i: commit score = %d\n", sinst->Instruction->IP, sinst->Score);

	commit_update_reads(s, sinst);

	commit_update_writes(s, sinst);

	if (get_tex_read_count(sinst) > 0) {
		sinst->Instruction->U.P.SemWait = 1;
		notify_sem_wait(s);
	}
}

/**
 * Emit all ready texture instructions in a single block.
 *
 * Emit as a single block to (hopefully) sample many textures in parallel,
 * and to avoid hardware indirections on R300.
 */
static void emit_all_tex(struct schedule_state * s, struct rc_instruction * before)
{
	struct schedule_instruction *readytex;
	struct rc_instruction * inst_begin;

	assert(s->ReadyTEX);
	notify_sem_wait(s);

	/* Node marker for R300 */
	inst_begin = rc_insert_new_instruction(s->C, before->Prev);
	inst_begin->U.I.Opcode = RC_OPCODE_BEGIN_TEX;

	/* Link texture instructions back in */
	readytex = s->ReadyTEX;
	while(readytex) {
		rc_insert_instruction(before->Prev, readytex->Instruction);
		DBG("%i: commit TEX reads\n", readytex->Instruction->IP);

		/* All of the TEX instructions in the same TEX block have
		 * their source registers read from before any of the
		 * instructions in that block write to their destination
		 * registers.  This means that when we commit a TEX
		 * instruction, any other TEX instruction that wants to write
		 * to one of the committed instruction's source register can be
		 * marked as ready and should be emitted in the same TEX
		 * block. This prevents the following sequence from being
		 * emitted in two different TEX blocks:
		 * 0: TEX temp[0].xyz, temp[1].xy__, 2D[0];
		 * 1: TEX temp[1].xyz, temp[2].xy__, 2D[0];
		 */
		commit_update_reads(s, readytex);
		readytex = readytex->NextReady;
	}
	readytex = s->ReadyTEX;
	s->ReadyTEX = 0;
	while(readytex){
		DBG("%i: commit TEX writes\n", readytex->Instruction->IP);
		commit_update_writes(s, readytex);
		/* Set semaphore bits for last TEX instruction in the block */
		if (!readytex->NextReady) {
			readytex->Instruction->U.I.TexSemAcquire = 1;
			readytex->Instruction->U.I.TexSemWait = 1;
		}
		rc_list_add(&s->PendingTEX, rc_list(&s->C->Pool, readytex));
		readytex = readytex->NextReady;
	}
}

/* This is a helper function for destructive_merge_instructions().  It helps
 * merge presubtract sources from two instructions and makes sure the
 * presubtract sources end up in the correct spot.  This function assumes that
 * dst_full is an rgb instruction, meaning that it has a vector instruction(rgb)
 * but no scalar instruction (alpha).
 * @return 0 if merging the presubtract sources fails.
 * @retrun 1 if merging the presubtract sources succeeds.
 */
static int merge_presub_sources(
	struct rc_pair_instruction * dst_full,
	struct rc_pair_sub_instruction src,
	unsigned int type)
{
	unsigned int srcp_src, srcp_regs, is_rgb, is_alpha;
	struct rc_pair_sub_instruction * dst_sub;
	const struct rc_opcode_info * info;

	assert(dst_full->Alpha.Opcode == RC_OPCODE_NOP);

	switch(type) {
	case RC_SOURCE_RGB:
		is_rgb = 1;
		is_alpha = 0;
		dst_sub = &dst_full->RGB;
		break;
	case RC_SOURCE_ALPHA:
		is_rgb = 0;
		is_alpha = 1;
		dst_sub = &dst_full->Alpha;
		break;
	default:
		assert(0);
		return 0;
	}

	info = rc_get_opcode_info(dst_full->RGB.Opcode);

	if (dst_sub->Src[RC_PAIR_PRESUB_SRC].Used)
		return 0;

	srcp_regs = rc_presubtract_src_reg_count(
					src.Src[RC_PAIR_PRESUB_SRC].Index);
	for(srcp_src = 0; srcp_src < srcp_regs; srcp_src++) {
		unsigned int arg;
		int free_source;
		unsigned int one_way = 0;
		struct rc_pair_instruction_source srcp = src.Src[srcp_src];
		struct rc_pair_instruction_source temp;

		free_source = rc_pair_alloc_source(dst_full, is_rgb, is_alpha,
							srcp.File, srcp.Index);

		/* If free_source < 0 then there are no free source
		 * slots. */
		if (free_source < 0)
			return 0;

		temp = dst_sub->Src[srcp_src];
		dst_sub->Src[srcp_src] = dst_sub->Src[free_source];

		/* srcp needs src0 and src1 to be the same */
		if (free_source < srcp_src) {
			if (!temp.Used)
				continue;
			free_source = rc_pair_alloc_source(dst_full, is_rgb,
					is_alpha, temp.File, temp.Index);
			if (free_source < 0)
				return 0;
			one_way = 1;
		} else {
			dst_sub->Src[free_source] = temp;
		}

		/* If free_source == srcp_src, then the presubtract
		 * source is already in the correct place. */
		if (free_source == srcp_src)
			continue;

		/* Shuffle the sources, so we can put the
		 * presubtract source in the correct place. */
		for(arg = 0; arg < info->NumSrcRegs; arg++) {
			/*If this arg does not read from an rgb source,
			 * do nothing. */
			if (!(rc_source_type_swz(dst_full->RGB.Arg[arg].Swizzle)
								& type)) {
				continue;
			}

			if (dst_full->RGB.Arg[arg].Source == srcp_src)
				dst_full->RGB.Arg[arg].Source = free_source;
			/* We need to do this just in case register
			 * is one of the sources already, but in the
			 * wrong spot. */
			else if(dst_full->RGB.Arg[arg].Source == free_source
							&& !one_way) {
				dst_full->RGB.Arg[arg].Source = srcp_src;
			}
		}
	}
	return 1;
}


/* This function assumes that rgb.Alpha and alpha.RGB are unused */
static int destructive_merge_instructions(
		struct rc_pair_instruction * rgb,
		struct rc_pair_instruction * alpha)
{
	const struct rc_opcode_info * opcode;

	assert(rgb->Alpha.Opcode == RC_OPCODE_NOP);
	assert(alpha->RGB.Opcode == RC_OPCODE_NOP);

	/* Presubtract registers need to be merged first so that registers
	 * needed by the presubtract operation can be placed in src0 and/or
	 * src1. */

	/* Merge the rgb presubtract registers. */
	if (alpha->RGB.Src[RC_PAIR_PRESUB_SRC].Used) {
		if (!merge_presub_sources(rgb, alpha->RGB, RC_SOURCE_RGB)) {
			return 0;
		}
	}
	/* Merge the alpha presubtract registers */
	if (alpha->Alpha.Src[RC_PAIR_PRESUB_SRC].Used) {
		if(!merge_presub_sources(rgb,  alpha->Alpha, RC_SOURCE_ALPHA)){
			return 0;
		}
	}

	/* Copy alpha args into rgb */
	opcode = rc_get_opcode_info(alpha->Alpha.Opcode);

	for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) {
		unsigned int srcrgb = 0;
		unsigned int srcalpha = 0;
		unsigned int oldsrc = alpha->Alpha.Arg[arg].Source;
		rc_register_file file = 0;
		unsigned int index = 0;
		int source;

		if (GET_SWZ(alpha->Alpha.Arg[arg].Swizzle, 0) < 3) {
			srcrgb = 1;
			file = alpha->RGB.Src[oldsrc].File;
			index = alpha->RGB.Src[oldsrc].Index;
		} else if (GET_SWZ(alpha->Alpha.Arg[arg].Swizzle, 0) < 4) {
			srcalpha = 1;
			file = alpha->Alpha.Src[oldsrc].File;
			index = alpha->Alpha.Src[oldsrc].Index;
		}

		source = rc_pair_alloc_source(rgb, srcrgb, srcalpha, file, index);
		if (source < 0)
			return 0;

		rgb->Alpha.Arg[arg].Source = source;
		rgb->Alpha.Arg[arg].Swizzle = alpha->Alpha.Arg[arg].Swizzle;
		rgb->Alpha.Arg[arg].Abs = alpha->Alpha.Arg[arg].Abs;
		rgb->Alpha.Arg[arg].Negate = alpha->Alpha.Arg[arg].Negate;
	}

	/* Copy alpha opcode into rgb */
	rgb->Alpha.Opcode = alpha->Alpha.Opcode;
	rgb->Alpha.DestIndex = alpha->Alpha.DestIndex;
	rgb->Alpha.WriteMask = alpha->Alpha.WriteMask;
	rgb->Alpha.OutputWriteMask = alpha->Alpha.OutputWriteMask;
	rgb->Alpha.DepthWriteMask = alpha->Alpha.DepthWriteMask;
	rgb->Alpha.Saturate = alpha->Alpha.Saturate;
	rgb->Alpha.Omod = alpha->Alpha.Omod;

	/* Merge ALU result writing */
	if (alpha->WriteALUResult) {
		if (rgb->WriteALUResult)
			return 0;

		rgb->WriteALUResult = alpha->WriteALUResult;
		rgb->ALUResultCompare = alpha->ALUResultCompare;
	}

	/* Copy SemWait */
	rgb->SemWait |= alpha->SemWait;

	return 1;
}

/**
 * Try to merge the given instructions into the rgb instructions.
 *
 * Return true on success; on failure, return false, and keep
 * the instructions untouched.
 */
static int merge_instructions(struct rc_pair_instruction * rgb, struct rc_pair_instruction * alpha)
{
	struct rc_pair_instruction backup;

	/*Instructions can't write output registers and ALU result at the
	 * same time. */
	if ((rgb->WriteALUResult && alpha->Alpha.OutputWriteMask)
		|| (rgb->RGB.OutputWriteMask && alpha->WriteALUResult)) {
		return 0;
	}

	/* Writing output registers in the middle of shaders is slow, so
	 * we don't want to pair output writes with temp writes. */
	if ((rgb->RGB.OutputWriteMask && !alpha->Alpha.OutputWriteMask)
		|| (!rgb->RGB.OutputWriteMask && alpha->Alpha.OutputWriteMask)) {
		return 0;
	}

	memcpy(&backup, rgb, sizeof(struct rc_pair_instruction));

	if (destructive_merge_instructions(rgb, alpha))
		return 1;

	memcpy(rgb, &backup, sizeof(struct rc_pair_instruction));
	return 0;
}

static void presub_nop(struct rc_instruction * emitted) {
	int prev_rgb_index, prev_alpha_index, i, num_src;

	/* We don't need a nop if the previous instruction is a TEX. */
	if (emitted->Prev->Type != RC_INSTRUCTION_PAIR) {
		return;
	}
	if (emitted->Prev->U.P.RGB.WriteMask)
		prev_rgb_index = emitted->Prev->U.P.RGB.DestIndex;
	else
		prev_rgb_index = -1;
	if (emitted->Prev->U.P.Alpha.WriteMask)
		prev_alpha_index = emitted->Prev->U.P.Alpha.DestIndex;
	else
		prev_alpha_index = 1;

	/* Check the previous rgb instruction */
	if (emitted->U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Used) {
		num_src = rc_presubtract_src_reg_count(
				emitted->U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Index);
		for (i = 0; i < num_src; i++) {
			unsigned int index = emitted->U.P.RGB.Src[i].Index;
			if (emitted->U.P.RGB.Src[i].File == RC_FILE_TEMPORARY
			    && (index  == prev_rgb_index
				|| index == prev_alpha_index)) {
				emitted->Prev->U.P.Nop = 1;
				return;
			}
		}
	}

	/* Check the previous alpha instruction. */
	if (!emitted->U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Used)
		return;

	num_src = rc_presubtract_src_reg_count(
				emitted->U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Index);
	for (i = 0; i < num_src; i++) {
		unsigned int index = emitted->U.P.Alpha.Src[i].Index;
		if(emitted->U.P.Alpha.Src[i].File == RC_FILE_TEMPORARY
		   && (index == prev_rgb_index || index == prev_alpha_index)) {
			emitted->Prev->U.P.Nop = 1;
			return;
		}
	}
}

static void rgb_to_alpha_remap (
	struct rc_instruction * inst,
	struct rc_pair_instruction_arg * arg,
	rc_register_file old_file,
	rc_swizzle old_swz,
	unsigned int new_index)
{
	int new_src_index;
	unsigned int i;

	for (i = 0; i < 3; i++) {
		if (get_swz(arg->Swizzle, i) == old_swz) {
			SET_SWZ(arg->Swizzle, i, RC_SWIZZLE_W);
		}
	}
	new_src_index = rc_pair_alloc_source(&inst->U.P, 0, 1,
							old_file, new_index);
	/* This conversion is not possible, we must have made a mistake in
	 * is_rgb_to_alpha_possible. */
	if (new_src_index < 0) {
		assert(0);
		return;
	}

	arg->Source = new_src_index;
}

static int can_remap(unsigned int opcode)
{
	switch(opcode) {
	case RC_OPCODE_DDX:
	case RC_OPCODE_DDY:
		return 0;
	default:
		return 1;
	}
}

static int can_convert_opcode_to_alpha(unsigned int opcode)
{
	switch(opcode) {
	case RC_OPCODE_DDX:
	case RC_OPCODE_DDY:
	case RC_OPCODE_DP2:
	case RC_OPCODE_DP3:
	case RC_OPCODE_DP4:
	case RC_OPCODE_DPH:
		return 0;
	default:
		return 1;
	}
}

static void is_rgb_to_alpha_possible(
	void * userdata,
	struct rc_instruction * inst,
	struct rc_pair_instruction_arg * arg,
	struct rc_pair_instruction_source * src)
{
	unsigned int read_chan = RC_SWIZZLE_UNUSED;
	unsigned int alpha_sources = 0;
	unsigned int i;
	struct rc_reader_data * reader_data = userdata;

	if (!can_remap(inst->U.P.RGB.Opcode)
	    || !can_remap(inst->U.P.Alpha.Opcode)) {
		reader_data->Abort = 1;
		return;
	}

	if (!src)
		return;

	/* XXX There are some cases where we can still do the conversion if
	 * a reader reads from a presubtract source, but for now we'll prevent
	 * it. */
	if (arg->Source == RC_PAIR_PRESUB_SRC) {
		reader_data->Abort = 1;
		return;
	}

	/* Make sure the source only reads the register component that we
	 * are going to be convering from.  It is OK if the instruction uses
	 * this component more than once.
	 * XXX If the index we will be converting to is the same as the
	 * current index, then it is OK to read from more than one component.
	 */
	for (i = 0; i < 3; i++) {
		rc_swizzle swz = get_swz(arg->Swizzle, i);
		switch(swz) {
		case RC_SWIZZLE_X:
		case RC_SWIZZLE_Y:
		case RC_SWIZZLE_Z:
		case RC_SWIZZLE_W:
			if (read_chan == RC_SWIZZLE_UNUSED) {
				read_chan = swz;
			} else if (read_chan != swz) {
				reader_data->Abort = 1;
				return;
			}
			break;
		default:
			break;
		}
	}

	/* Make sure there are enough alpha sources.
	 * XXX If we know what register all the readers are going
	 * to be remapped to, then in some situations we can still do
	 * the subsitution, even if all 3 alpha sources are being used.*/
	for (i = 0; i < 3; i++) {
		if (inst->U.P.Alpha.Src[i].Used) {
			alpha_sources++;
		}
	}
	if (alpha_sources > 2) {
		reader_data->Abort = 1;
		return;
	}
}

static int convert_rgb_to_alpha(
	struct schedule_state * s,
	struct schedule_instruction * sched_inst)
{
	struct rc_pair_instruction * pair_inst = &sched_inst->Instruction->U.P;
	unsigned int old_mask = pair_inst->RGB.WriteMask;
	unsigned int old_swz = rc_mask_to_swizzle(old_mask);
	const struct rc_opcode_info * info =
				rc_get_opcode_info(pair_inst->RGB.Opcode);
	int new_index = -1;
	unsigned int i;

	if (sched_inst->GlobalReaders.Abort)
		return 0;

	if (!pair_inst->RGB.WriteMask)
		return 0;

	if (!can_convert_opcode_to_alpha(pair_inst->RGB.Opcode)
	    || !can_convert_opcode_to_alpha(pair_inst->Alpha.Opcode)) {
		return 0;
	}

	assert(sched_inst->NumWriteValues == 1);

	if (!sched_inst->WriteValues[0]) {
		assert(0);
		return 0;
	}

	/* We start at the old index, because if we can reuse the same
	 * register and just change the swizzle then it is more likely we
	 * will be able to convert all the readers. */
	for (i = pair_inst->RGB.DestIndex; i < RC_REGISTER_MAX_INDEX; i++) {
		struct reg_value ** new_regvalp = get_reg_valuep(
						s, RC_FILE_TEMPORARY, i, 3);
		if (!*new_regvalp) {
			struct reg_value ** old_regvalp =
				get_reg_valuep(s,
					RC_FILE_TEMPORARY,
					pair_inst->RGB.DestIndex,
					rc_mask_to_swizzle(old_mask));
			new_index = i;
			*new_regvalp = *old_regvalp;
			*old_regvalp = NULL;
			new_regvalp = get_reg_valuep(s, RC_FILE_TEMPORARY, i, 3);
			break;
		}
	}
	if (new_index < 0) {
		return 0;
	}

	/* If we are converting a full instruction with RC_OPCODE_REPL_ALPHA
	 * as the RGB opcode, then the Alpha instruction will already contain
	 * the correct opcode and instruction args, so we do not want to
	 * overwrite them.
	 */
	if (pair_inst->RGB.Opcode != RC_OPCODE_REPL_ALPHA) {
		pair_inst->Alpha.Opcode = pair_inst->RGB.Opcode;
		memcpy(pair_inst->Alpha.Arg, pair_inst->RGB.Arg,
						sizeof(pair_inst->Alpha.Arg));
	}
	pair_inst->Alpha.DestIndex = new_index;
	pair_inst->Alpha.WriteMask = RC_MASK_W;
	pair_inst->Alpha.Target = pair_inst->RGB.Target;
	pair_inst->Alpha.OutputWriteMask = pair_inst->RGB.OutputWriteMask;
	pair_inst->Alpha.DepthWriteMask = pair_inst->RGB.DepthWriteMask;
	pair_inst->Alpha.Saturate = pair_inst->RGB.Saturate;
	pair_inst->Alpha.Omod = pair_inst->RGB.Omod;
	/* Move the swizzles into the first chan */
	for (i = 0; i < info->NumSrcRegs; i++) {
		unsigned int j;
		for (j = 0; j < 3; j++) {
			unsigned int swz = get_swz(pair_inst->Alpha.Arg[i].Swizzle, j);
			if (swz != RC_SWIZZLE_UNUSED) {
				pair_inst->Alpha.Arg[i].Swizzle =
							rc_init_swizzle(swz, 1);
				break;
			}
		}
	}
	pair_inst->RGB.Opcode = RC_OPCODE_NOP;
	pair_inst->RGB.DestIndex = 0;
	pair_inst->RGB.WriteMask = 0;
	pair_inst->RGB.Target = 0;
	pair_inst->RGB.OutputWriteMask = 0;
	pair_inst->RGB.DepthWriteMask = 0;
	pair_inst->RGB.Saturate = 0;
	memset(pair_inst->RGB.Arg, 0, sizeof(pair_inst->RGB.Arg));

	for(i = 0; i < sched_inst->GlobalReaders.ReaderCount; i++) {
		struct rc_reader reader = sched_inst->GlobalReaders.Readers[i];
		rgb_to_alpha_remap(reader.Inst, reader.U.P.Arg,
					RC_FILE_TEMPORARY, old_swz, new_index);
	}
	return 1;
}

static void try_convert_and_pair(
	struct schedule_state *s,
	struct schedule_instruction ** inst_list)
{
	struct schedule_instruction * list_ptr = *inst_list;
	while (list_ptr && *inst_list && (*inst_list)->NextReady) {
		int paired = 0;
		if (list_ptr->Instruction->U.P.Alpha.Opcode != RC_OPCODE_NOP
			&& list_ptr->Instruction->U.P.RGB.Opcode
						!= RC_OPCODE_REPL_ALPHA) {
				goto next;
		}
		if (list_ptr->NumWriteValues == 1
					&& convert_rgb_to_alpha(s, list_ptr)) {

			struct schedule_instruction * pair_ptr;
			remove_inst_from_list(inst_list, list_ptr);
			add_inst_to_list_score(&s->ReadyAlpha, list_ptr);

			for (pair_ptr = s->ReadyRGB; pair_ptr;
					pair_ptr = pair_ptr->NextReady) {
				if (merge_instructions(&pair_ptr->Instruction->U.P,
						&list_ptr->Instruction->U.P)) {
					remove_inst_from_list(&s->ReadyAlpha, list_ptr);
					remove_inst_from_list(&s->ReadyRGB, pair_ptr);
					pair_ptr->PairedInst = list_ptr;

					add_inst_to_list(&s->ReadyFullALU, pair_ptr);
					list_ptr = *inst_list;
					paired = 1;
					break;
				}

			}
		}
		if (!paired) {
next:
			list_ptr = list_ptr->NextReady;
		}
	}
}

/**
 * This function attempts to merge RGB and Alpha instructions together.
 */
static void pair_instructions(struct schedule_state * s)
{
	struct schedule_instruction *rgb_ptr;
	struct schedule_instruction *alpha_ptr;

	/* Some pairings might fail because they require too
	 * many source slots; try all possible pairings if necessary */
	rgb_ptr = s->ReadyRGB;
	while(rgb_ptr) {
		struct schedule_instruction * rgb_next = rgb_ptr->NextReady;
		alpha_ptr = s->ReadyAlpha;
		while(alpha_ptr) {
			struct schedule_instruction * alpha_next = alpha_ptr->NextReady;
			if (merge_instructions(&rgb_ptr->Instruction->U.P, &alpha_ptr->Instruction->U.P)) {
				/* Remove RGB and Alpha from their ready lists.
				 */
				remove_inst_from_list(&s->ReadyRGB, rgb_ptr);
				remove_inst_from_list(&s->ReadyAlpha, alpha_ptr);
				rgb_ptr->PairedInst = alpha_ptr;
				add_inst_to_list(&s->ReadyFullALU, rgb_ptr);
				break;
			}
			alpha_ptr = alpha_next;
		}
		rgb_ptr = rgb_next;
	}

	if (!s->Opt) {
		return;
	}

	/* Full instructions that have RC_OPCODE_REPL_ALPHA in the RGB
	 * slot can be converted into Alpha instructions. */
	try_convert_and_pair(s, &s->ReadyFullALU);

	/* Try to convert some of the RGB instructions to Alpha and
	 * try to pair it with another RGB. */
	try_convert_and_pair(s, &s->ReadyRGB);
}

static void update_max_score(
	struct schedule_state * s,
	struct schedule_instruction ** list,
	int * max_score,
	struct schedule_instruction ** max_inst_out,
	struct schedule_instruction *** list_out)
{
	struct schedule_instruction * list_ptr;
	for (list_ptr = *list; list_ptr; list_ptr = list_ptr->NextReady) {
		int score;
		s->CalcScore(list_ptr);
		score = list_ptr->Score;
		if (!*max_inst_out || score > *max_score) {
			*max_score = score;
			*max_inst_out = list_ptr;
			*list_out = list;
		}
	}
}

static void emit_instruction(
	struct schedule_state * s,
	struct rc_instruction * before)
{
	int max_score = -1;
	struct schedule_instruction * max_inst = NULL;
	struct schedule_instruction ** max_list = NULL;
	unsigned tex_count = 0;
	struct schedule_instruction * tex_ptr;

	pair_instructions(s);
#if VERBOSE
	fprintf(stderr, "Full:\n");
	print_list(s->ReadyFullALU);
	fprintf(stderr, "RGB:\n");
	print_list(s->ReadyRGB);
	fprintf(stderr, "Alpha:\n");
	print_list(s->ReadyAlpha);
	fprintf(stderr, "TEX:\n");
	print_list(s->ReadyTEX);
#endif

	for (tex_ptr = s->ReadyTEX; tex_ptr; tex_ptr = tex_ptr->NextReady) {
		if (tex_ptr->Instruction->U.I.Opcode == RC_OPCODE_KIL) {
			emit_all_tex(s, before);
			return;
		}
		tex_count++;
	}
	update_max_score(s, &s->ReadyFullALU, &max_score, &max_inst, &max_list);
	update_max_score(s, &s->ReadyRGB, &max_score, &max_inst, &max_list);
	update_max_score(s, &s->ReadyAlpha, &max_score, &max_inst, &max_list);

	if (tex_count >= s->max_tex_group || max_score == -1
		|| (s->TEXCount > 0 && tex_count == s->TEXCount)
		|| (!s->C->is_r500 && tex_count > 0 && max_score == -1)) {
		emit_all_tex(s, before);
	} else {


		remove_inst_from_list(max_list, max_inst);
		rc_insert_instruction(before->Prev, max_inst->Instruction);
		commit_alu_instruction(s, max_inst);

		presub_nop(before->Prev);
	}
}

static void add_tex_reader(
	struct schedule_state * s,
	struct schedule_instruction * writer,
	struct schedule_instruction * reader)
{
	if (!writer || writer->Instruction->Type != RC_INSTRUCTION_NORMAL) {
		/*Not a TEX instructions */
		return;
	}
	reader->TexReadCount++;
	rc_list_add(&writer->TexReaders, rc_list(&s->C->Pool, reader));
}

static void scan_read(void * data, struct rc_instruction * inst,
		rc_register_file file, unsigned int index, unsigned int chan)
{
	struct schedule_state * s = data;
	struct reg_value ** v = get_reg_valuep(s, file, index, chan);
	struct reg_value_reader * reader;

	if (!v)
		return;

	if (*v && (*v)->Writer == s->Current) {
		/* The instruction reads and writes to a register component.
		 * In this case, we only want to increment dependencies by one.
		 * Why?
		 * Because each instruction depends on the writers of its source
		 * registers _and_ the most recent writer of its destination
		 * register.  In this case, the current instruction (s->Current)
		 * has a dependency that both writes to one of its source
		 * registers and was the most recent writer to its destination
		 * register.  We have already marked this dependency in
		 * scan_write(), so we don't need to do it again.
		 */

		/* We need to make sure we are adding s->Current to the
		 * previous writer's list of TexReaders, if the previous writer
		 * was a TEX instruction.
		 */
		add_tex_reader(s, s->PrevWriter[chan], s->Current);

		return;
	}

	DBG("%i: read %i[%i] chan %i\n", s->Current->Instruction->IP, file, index, chan);

	reader = memory_pool_malloc(&s->C->Pool, sizeof(*reader));
	reader->Reader = s->Current;
	if (!*v) {
		/* In this situation, the instruction reads from a register
		 * that hasn't been written to or read from in the current
		 * block. */
		*v = memory_pool_malloc(&s->C->Pool, sizeof(struct reg_value));
		memset(*v, 0, sizeof(struct reg_value));
		(*v)->Readers = reader;
	} else {
		reader->Next = (*v)->Readers;
		(*v)->Readers = reader;
		/* Only update the current instruction's dependencies if the
		 * register it reads from has been written to in this block. */
		if ((*v)->Writer) {
			add_tex_reader(s, (*v)->Writer, s->Current);
			s->Current->NumDependencies++;
		}
	}
	(*v)->NumReaders++;

	if (s->Current->NumReadValues >= 12) {
		rc_error(s->C, "%s: NumReadValues overflow\n", __FUNCTION__);
	} else {
		s->Current->ReadValues[s->Current->NumReadValues++] = *v;
	}
}

static void scan_write(void * data, struct rc_instruction * inst,
		rc_register_file file, unsigned int index, unsigned int chan)
{
	struct schedule_state * s = data;
	struct reg_value ** pv = get_reg_valuep(s, file, index, chan);
	struct reg_value * newv;

	if (!pv)
		return;

	DBG("%i: write %i[%i] chan %i\n", s->Current->Instruction->IP, file, index, chan);

	newv = memory_pool_malloc(&s->C->Pool, sizeof(*newv));
	memset(newv, 0, sizeof(*newv));

	newv->Writer = s->Current;

	if (*pv) {
		(*pv)->Next = newv;
		s->Current->NumDependencies++;
		/* Keep track of the previous writer to s->Current's destination
		 * register */
		s->PrevWriter[chan] = (*pv)->Writer;
	}

	*pv = newv;

	if (s->Current->NumWriteValues >= 4) {
		rc_error(s->C, "%s: NumWriteValues overflow\n", __FUNCTION__);
	} else {
		s->Current->WriteValues[s->Current->NumWriteValues++] = newv;
	}
}

static void is_rgb_to_alpha_possible_normal(
	void * userdata,
	struct rc_instruction * inst,
	struct rc_src_register * src)
{
	struct rc_reader_data * reader_data = userdata;
	reader_data->Abort = 1;

}

static void schedule_block(struct schedule_state * s,
		struct rc_instruction * begin, struct rc_instruction * end)
{
	unsigned int ip;

	/* Scan instructions for data dependencies */
	ip = 0;
	for(struct rc_instruction * inst = begin; inst != end; inst = inst->Next) {
		s->Current = memory_pool_malloc(&s->C->Pool, sizeof(*s->Current));
		memset(s->Current, 0, sizeof(struct schedule_instruction));

		if (inst->Type == RC_INSTRUCTION_NORMAL) {
			const struct rc_opcode_info * info =
					rc_get_opcode_info(inst->U.I.Opcode);
			if (info->HasTexture) {
				s->TEXCount++;
			}
		}

		/* XXX: This causes SemWait to be set for all instructions in
		 * a block if the previous block contained a TEX instruction.
		 * We can do better here, but it will take a lot of work. */
		if (s->PrevBlockHasTex) {
			s->Current->TexReadCount = 1;
		}

		s->Current->Instruction = inst;
		inst->IP = ip++;

		DBG("%i: Scanning\n", inst->IP);

		/* The order of things here is subtle and maybe slightly
		 * counter-intuitive, to account for the case where an
		 * instruction writes to the same register as it reads
		 * from. */
		rc_for_all_writes_chan(inst, &scan_write, s);
		rc_for_all_reads_chan(inst, &scan_read, s);

		DBG("%i: Has %i dependencies\n", inst->IP, s->Current->NumDependencies);

		if (!s->Current->NumDependencies) {
			instruction_ready(s, s->Current);
		}

		/* Get global readers for possible RGB->Alpha conversion. */
		s->Current->GlobalReaders.ExitOnAbort = 1;
		rc_get_readers(s->C, inst, &s->Current->GlobalReaders,
				is_rgb_to_alpha_possible_normal,
				is_rgb_to_alpha_possible, NULL);
	}

	/* Temporarily unlink all instructions */
	begin->Prev->Next = end;
	end->Prev = begin->Prev;

	/* Schedule instructions back */
	while(!s->C->Error &&
	      (s->ReadyTEX || s->ReadyRGB || s->ReadyAlpha || s->ReadyFullALU)) {
		emit_instruction(s, end);
	}
}

static int is_controlflow(struct rc_instruction * inst)
{
	if (inst->Type == RC_INSTRUCTION_NORMAL) {
		const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
		return opcode->IsFlowControl;
	}
	return 0;
}

void rc_pair_schedule(struct radeon_compiler *cc, void *user)
{
	struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)cc;
	struct schedule_state s;
	struct rc_instruction * inst = c->Base.Program.Instructions.Next;
	unsigned int * opt = user;

	memset(&s, 0, sizeof(s));
	s.Opt = *opt;
	s.C = &c->Base;
	if (s.C->is_r500) {
		s.CalcScore = calc_score_readers;
	} else {
		s.CalcScore = calc_score_r300;
	}
	s.max_tex_group = debug_get_num_option("RADEON_TEX_GROUP", 8);
	while(inst != &c->Base.Program.Instructions) {
		struct rc_instruction * first;

		if (is_controlflow(inst)) {
			inst = inst->Next;
			continue;
		}

		first = inst;

		while(inst != &c->Base.Program.Instructions && !is_controlflow(inst))
			inst = inst->Next;

		DBG("Schedule one block\n");
		memset(s.Temporary, 0, sizeof(s.Temporary));
		s.TEXCount = 0;
		schedule_block(&s, first, inst);
		if (s.PendingTEX) {
			s.PrevBlockHasTex = 1;
		}
	}
}
