/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 AUTHORS OR COPYRIGHT HOLDERS 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 "main/core.h"
#include "glsl_symbol_table.h"
#include "glsl_parser_extras.h"
#include "ir.h"
#include "program.h"
#include "program/hash_table.h"
#include "linker.h"

static ir_function_signature *
find_matching_signature(const char *name, const exec_list *actual_parameters,
			gl_shader **shader_list, unsigned num_shaders,
			bool use_builtin);

class call_link_visitor : public ir_hierarchical_visitor {
public:
   call_link_visitor(gl_shader_program *prog, gl_shader *linked,
		     gl_shader **shader_list, unsigned num_shaders)
   {
      this->prog = prog;
      this->shader_list = shader_list;
      this->num_shaders = num_shaders;
      this->success = true;
      this->linked = linked;

      this->locals = hash_table_ctor(0, hash_table_pointer_hash,
				     hash_table_pointer_compare);
   }

   ~call_link_visitor()
   {
      hash_table_dtor(this->locals);
   }

   virtual ir_visitor_status visit(ir_variable *ir)
   {
      hash_table_insert(locals, ir, ir);
      return visit_continue;
   }

   virtual ir_visitor_status visit_enter(ir_call *ir)
   {
      /* If ir is an ir_call from a function that was imported from another
       * shader callee will point to an ir_function_signature in the original
       * shader.  In this case the function signature MUST NOT BE MODIFIED.
       * Doing so will modify the original shader.  This may prevent that
       * shader from being linkable in other programs.
       */
      const ir_function_signature *const callee = ir->callee;
      assert(callee != NULL);
      const char *const name = callee->function_name();

      /* Determine if the requested function signature already exists in the
       * final linked shader.  If it does, use it as the target of the call.
       */
      ir_function_signature *sig =
	 find_matching_signature(name, &callee->parameters, &linked, 1,
				 ir->use_builtin);
      if (sig != NULL) {
	 ir->callee = sig;
	 return visit_continue;
      }

      /* Try to find the signature in one of the other shaders that is being
       * linked.  If it's not found there, return an error.
       */
      sig = find_matching_signature(name, &ir->actual_parameters, shader_list,
				    num_shaders, ir->use_builtin);
      if (sig == NULL) {
	 /* FINISHME: Log the full signature of unresolved function.
	  */
	 linker_error(this->prog, "unresolved reference to function `%s'\n",
		      name);
	 this->success = false;
	 return visit_stop;
      }

      /* Find the prototype information in the linked shader.  Generate any
       * details that may be missing.
       */
      ir_function *f = linked->symbols->get_function(name);
      if (f == NULL) {
	 f = new(linked) ir_function(name);

	 /* Add the new function to the linked IR.  Put it at the end
          * so that it comes after any global variable declarations
          * that it refers to.
	  */
	 linked->symbols->add_function(f);
	 linked->ir->push_tail(f);
      }

      ir_function_signature *linked_sig =
	 f->exact_matching_signature(&callee->parameters);
      if ((linked_sig == NULL)
	  || ((linked_sig != NULL)
	      && (linked_sig->is_builtin != ir->use_builtin))) {
	 linked_sig = new(linked) ir_function_signature(callee->return_type);
	 f->add_signature(linked_sig);
      }

      /* At this point linked_sig and called may be the same.  If ir is an
       * ir_call from linked then linked_sig and callee will be
       * ir_function_signatures that have no definitions (is_defined is false).
       */
      assert(!linked_sig->is_defined);
      assert(linked_sig->body.is_empty());

      /* Create an in-place clone of the function definition.  This multistep
       * process introduces some complexity here, but it has some advantages.
       * The parameter list and the and function body are cloned separately.
       * The clone of the parameter list is used to prime the hashtable used
       * to replace variable references in the cloned body.
       *
       * The big advantage is that the ir_function_signature does not change.
       * This means that we don't have to process the rest of the IR tree to
       * patch ir_call nodes.  In addition, there is no way to remove or
       * replace signature stored in a function.  One could easily be added,
       * but this avoids the need.
       */
      struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash,
					      hash_table_pointer_compare);
      exec_list formal_parameters;
      foreach_list_const(node, &sig->parameters) {
	 const ir_instruction *const original = (ir_instruction *) node;
	 assert(const_cast<ir_instruction *>(original)->as_variable());

	 ir_instruction *copy = original->clone(linked, ht);
	 formal_parameters.push_tail(copy);
      }

      linked_sig->replace_parameters(&formal_parameters);

      foreach_list_const(node, &sig->body) {
	 const ir_instruction *const original = (ir_instruction *) node;

	 ir_instruction *copy = original->clone(linked, ht);
	 linked_sig->body.push_tail(copy);
      }

      linked_sig->is_defined = true;
      hash_table_dtor(ht);

      /* Patch references inside the function to things outside the function
       * (i.e., function calls and global variables).
       */
      linked_sig->accept(this);

      ir->callee = linked_sig;

      return visit_continue;
   }

   virtual ir_visitor_status visit(ir_dereference_variable *ir)
   {
      if (hash_table_find(locals, ir->var) == NULL) {
	 /* The non-function variable must be a global, so try to find the
	  * variable in the shader's symbol table.  If the variable is not
	  * found, then it's a global that *MUST* be defined in the original
	  * shader.
	  */
	 ir_variable *var = linked->symbols->get_variable(ir->var->name);
	 if (var == NULL) {
	    /* Clone the ir_variable that the dereference already has and add
	     * it to the linked shader.
	     */
	    var = ir->var->clone(linked, NULL);
	    linked->symbols->add_variable(var);
	    linked->ir->push_head(var);
	 } else if (var->type->is_array()) {
	    /* It is possible to have a global array declared in multiple
	     * shaders without a size.  The array is implicitly sized by the
	     * maximal access to it in *any* shader.  Because of this, we
	     * need to track the maximal access to the array as linking pulls
	     * more functions in that access the array.
	     */
	    var->max_array_access =
	       MAX2(var->max_array_access, ir->var->max_array_access);

	    if (var->type->length == 0 && ir->var->type->length != 0)
	       var->type = ir->var->type;
	 }

	 ir->var = var;
      }

      return visit_continue;
   }

   /** Was function linking successful? */
   bool success;

private:
   /**
    * Shader program being linked
    *
    * This is only used for logging error messages.
    */
   gl_shader_program *prog;

   /** List of shaders available for linking. */
   gl_shader **shader_list;

   /** Number of shaders available for linking. */
   unsigned num_shaders;

   /**
    * Final linked shader
    *
    * This is used two ways.  It is used to find global variables in the
    * linked shader that are accessed by the function.  It is also used to add
    * global variables from the shader where the function originated.
    */
   gl_shader *linked;

   /**
    * Table of variables local to the function.
    */
   hash_table *locals;
};


/**
 * Searches a list of shaders for a particular function definition
 */
ir_function_signature *
find_matching_signature(const char *name, const exec_list *actual_parameters,
			gl_shader **shader_list, unsigned num_shaders,
			bool use_builtin)
{
   for (unsigned i = 0; i < num_shaders; i++) {
      ir_function *const f = shader_list[i]->symbols->get_function(name);

      if (f == NULL)
	 continue;

      ir_function_signature *sig = f->matching_signature(actual_parameters);

      if ((sig == NULL) || !sig->is_defined)
	 continue;

      /* If this function expects to bind to a built-in function and the
       * signature that we found isn't a built-in, keep looking.  Also keep
       * looking if we expect a non-built-in but found a built-in.
       */
      if (use_builtin != sig->is_builtin)
	    continue;

      return sig;
   }

   return NULL;
}


bool
link_function_calls(gl_shader_program *prog, gl_shader *main,
		    gl_shader **shader_list, unsigned num_shaders)
{
   call_link_visitor v(prog, main, shader_list, num_shaders);

   v.run(main->ir);
   return v.success;
}
