// SPDX-License-Identifier: GPL-2.0
#include "block-range.h"
#include "annotate.h"
#include <assert.h>
#include <stdlib.h>

struct {
	struct rb_root root;
	u64 blocks;
} block_ranges;

static void block_range__debug(void)
{
#ifndef NDEBUG
	struct rb_node *rb;
	u64 old = 0; /* NULL isn't executable */

	for (rb = rb_first(&block_ranges.root); rb; rb = rb_next(rb)) {
		struct block_range *entry = rb_entry(rb, struct block_range, node);

		assert(old < entry->start);
		assert(entry->start <= entry->end); /* single instruction block; jump to a jump */

		old = entry->end;
	}
#endif
}

struct block_range *block_range__find(u64 addr)
{
	struct rb_node **p = &block_ranges.root.rb_node;
	struct rb_node *parent = NULL;
	struct block_range *entry;

	while (*p != NULL) {
		parent = *p;
		entry = rb_entry(parent, struct block_range, node);

		if (addr < entry->start)
			p = &parent->rb_left;
		else if (addr > entry->end)
			p = &parent->rb_right;
		else
			return entry;
	}

	return NULL;
}

static inline void rb_link_left_of_node(struct rb_node *left, struct rb_node *node)
{
	struct rb_node **p = &node->rb_left;
	while (*p) {
		node = *p;
		p = &node->rb_right;
	}
	rb_link_node(left, node, p);
}

static inline void rb_link_right_of_node(struct rb_node *right, struct rb_node *node)
{
	struct rb_node **p = &node->rb_right;
	while (*p) {
		node = *p;
		p = &node->rb_left;
	}
	rb_link_node(right, node, p);
}

/**
 * block_range__create
 * @start: branch target starting this basic block
 * @end:   branch ending this basic block
 *
 * Create all the required block ranges to precisely span the given range.
 */
struct block_range_iter block_range__create(u64 start, u64 end)
{
	struct rb_node **p = &block_ranges.root.rb_node;
	struct rb_node *n, *parent = NULL;
	struct block_range *next, *entry = NULL;
	struct block_range_iter iter = { NULL, NULL };

	while (*p != NULL) {
		parent = *p;
		entry = rb_entry(parent, struct block_range, node);

		if (start < entry->start)
			p = &parent->rb_left;
		else if (start > entry->end)
			p = &parent->rb_right;
		else
			break;
	}

	/*
	 * Didn't find anything.. there's a hole at @start, however @end might
	 * be inside/behind the next range.
	 */
	if (!*p) {
		if (!entry) /* tree empty */
			goto do_whole;

		/*
		 * If the last node is before, advance one to find the next.
		 */
		n = parent;
		if (entry->end < start) {
			n = rb_next(n);
			if (!n)
				goto do_whole;
		}
		next = rb_entry(n, struct block_range, node);

		if (next->start <= end) { /* add head: [start...][n->start...] */
			struct block_range *head = malloc(sizeof(struct block_range));
			if (!head)
				return iter;

			*head = (struct block_range){
				.start		= start,
				.end		= next->start - 1,
				.is_target	= 1,
				.is_branch	= 0,
			};

			rb_link_left_of_node(&head->node, &next->node);
			rb_insert_color(&head->node, &block_ranges.root);
			block_range__debug();

			iter.start = head;
			goto do_tail;
		}

do_whole:
		/*
		 * The whole [start..end] range is non-overlapping.
		 */
		entry = malloc(sizeof(struct block_range));
		if (!entry)
			return iter;

		*entry = (struct block_range){
			.start		= start,
			.end		= end,
			.is_target	= 1,
			.is_branch	= 1,
		};

		rb_link_node(&entry->node, parent, p);
		rb_insert_color(&entry->node, &block_ranges.root);
		block_range__debug();

		iter.start = entry;
		iter.end   = entry;
		goto done;
	}

	/*
	 * We found a range that overlapped with ours, split if needed.
	 */
	if (entry->start < start) { /* split: [e->start...][start...] */
		struct block_range *head = malloc(sizeof(struct block_range));
		if (!head)
			return iter;

		*head = (struct block_range){
			.start		= entry->start,
			.end		= start - 1,
			.is_target	= entry->is_target,
			.is_branch	= 0,

			.coverage	= entry->coverage,
			.entry		= entry->entry,
		};

		entry->start		= start;
		entry->is_target	= 1;
		entry->entry		= 0;

		rb_link_left_of_node(&head->node, &entry->node);
		rb_insert_color(&head->node, &block_ranges.root);
		block_range__debug();

	} else if (entry->start == start)
		entry->is_target = 1;

	iter.start = entry;

do_tail:
	/*
	 * At this point we've got: @iter.start = [@start...] but @end can still be
	 * inside or beyond it.
	 */
	entry = iter.start;
	for (;;) {
		/*
		 * If @end is inside @entry, split.
		 */
		if (end < entry->end) { /* split: [...end][...e->end] */
			struct block_range *tail = malloc(sizeof(struct block_range));
			if (!tail)
				return iter;

			*tail = (struct block_range){
				.start		= end + 1,
				.end		= entry->end,
				.is_target	= 0,
				.is_branch	= entry->is_branch,

				.coverage	= entry->coverage,
				.taken		= entry->taken,
				.pred		= entry->pred,
			};

			entry->end		= end;
			entry->is_branch	= 1;
			entry->taken		= 0;
			entry->pred		= 0;

			rb_link_right_of_node(&tail->node, &entry->node);
			rb_insert_color(&tail->node, &block_ranges.root);
			block_range__debug();

			iter.end = entry;
			goto done;
		}

		/*
		 * If @end matches @entry, done
		 */
		if (end == entry->end) {
			entry->is_branch = 1;
			iter.end = entry;
			goto done;
		}

		next = block_range__next(entry);
		if (!next)
			goto add_tail;

		/*
		 * If @end is in beyond @entry but not inside @next, add tail.
		 */
		if (end < next->start) { /* add tail: [...e->end][...end] */
			struct block_range *tail;
add_tail:
			tail = malloc(sizeof(struct block_range));
			if (!tail)
				return iter;

			*tail = (struct block_range){
				.start		= entry->end + 1,
				.end		= end,
				.is_target	= 0,
				.is_branch	= 1,
			};

			rb_link_right_of_node(&tail->node, &entry->node);
			rb_insert_color(&tail->node, &block_ranges.root);
			block_range__debug();

			iter.end = tail;
			goto done;
		}

		/*
		 * If there is a hole between @entry and @next, fill it.
		 */
		if (entry->end + 1 != next->start) {
			struct block_range *hole = malloc(sizeof(struct block_range));
			if (!hole)
				return iter;

			*hole = (struct block_range){
				.start		= entry->end + 1,
				.end		= next->start - 1,
				.is_target	= 0,
				.is_branch	= 0,
			};

			rb_link_left_of_node(&hole->node, &next->node);
			rb_insert_color(&hole->node, &block_ranges.root);
			block_range__debug();
		}

		entry = next;
	}

done:
	assert(iter.start->start == start && iter.start->is_target);
	assert(iter.end->end == end && iter.end->is_branch);

	block_ranges.blocks++;

	return iter;
}


/*
 * Compute coverage as:
 *
 *    br->coverage / br->sym->max_coverage
 *
 * This ensures each symbol has a 100% spot, to reflect that each symbol has a
 * most covered section.
 *
 * Returns [0-1] for coverage and -1 if we had no data what so ever or the
 * symbol does not exist.
 */
double block_range__coverage(struct block_range *br)
{
	struct symbol *sym;

	if (!br) {
		if (block_ranges.blocks)
			return 0;

		return -1;
	}

	sym = br->sym;
	if (!sym)
		return -1;

	return (double)br->coverage / symbol__annotation(sym)->max_coverage;
}
