⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slang_codegen.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
      scope->outer_scope = fun->parameters;      /* create local var 't' */      var = slang_variable_scope_grow(scope);      var->a_name = slang_atom_pool_atom(A->atoms, "t");      var->type = fun->header.type;      /* declare t */      {         slang_operation *decl;         decl = &fun->body->children[0];         decl->type = SLANG_OPER_VARIABLE_DECL;         decl->locals = _slang_variable_scope_new(scope);         decl->a_id = var->a_name;      }      /* assign params to fields of t */      for (i = 0; i < numFields; i++) {         slang_operation *assign = &fun->body->children[1 + i];         assign->type = SLANG_OPER_ASSIGN;         assign->locals = _slang_variable_scope_new(scope);         assign->num_children = 2;         assign->children = slang_operation_new(2);                  {            slang_operation *lhs = &assign->children[0];            lhs->type = SLANG_OPER_FIELD;            lhs->locals = _slang_variable_scope_new(scope);            lhs->num_children = 1;            lhs->children = slang_operation_new(1);            lhs->a_id = str->fields->variables[i]->a_name;            lhs->children[0].type = SLANG_OPER_IDENTIFIER;            lhs->children[0].a_id = var->a_name;            lhs->children[0].locals = _slang_variable_scope_new(scope);#if 0            lhs->children[1].num_children = 1;            lhs->children[1].children = slang_operation_new(1);            lhs->children[1].children[0].type = SLANG_OPER_IDENTIFIER;            lhs->children[1].children[0].a_id = str->fields->variables[i]->a_name;            lhs->children[1].children->locals = _slang_variable_scope_new(scope);#endif         }         {            slang_operation *rhs = &assign->children[1];            rhs->type = SLANG_OPER_IDENTIFIER;            rhs->locals = _slang_variable_scope_new(scope);            rhs->a_id = str->fields->variables[i]->a_name;         }               }      /* return t; */      {         slang_operation *ret = &fun->body->children[numFields + 1];         ret->type = SLANG_OPER_RETURN;         ret->locals = _slang_variable_scope_new(scope);         ret->num_children = 1;         ret->children = slang_operation_new(1);         ret->children[0].type = SLANG_OPER_IDENTIFIER;         ret->children[0].a_id = var->a_name;         ret->children[0].locals = _slang_variable_scope_new(scope);      }   }   /*   slang_print_function(fun, 1);   */   return fun;}/** * Find/create a function (constructor) for the given structure name. */static slang_function *_slang_locate_struct_constructor(slang_assemble_ctx *A, const char *name){   unsigned int i;   for (i = 0; i < A->space.structs->num_structs; i++) {      slang_struct *str = &A->space.structs->structs[i];      if (strcmp(name, (const char *) str->a_name) == 0) {         /* found a structure type that matches the function name */         if (!str->constructor) {            /* create the constructor function now */            str->constructor = _slang_make_constructor(A, str);         }         return str->constructor;      }   }   return NULL;}static GLboolean_slang_is_vec_mat_type(const char *name){   static const char *vecmat_types[] = {      "float", "int", "bool",      "vec2", "vec3", "vec4",      "ivec2", "ivec3", "ivec4",      "bvec2", "bvec3", "bvec4",      "mat2", "mat3", "mat4",      "mat2x3", "mat2x4", "mat3x2", "mat3x4", "mat4x2", "mat4x3",      NULL   };   int i;   for (i = 0; vecmat_types[i]; i++)      if (_mesa_strcmp(name, vecmat_types[i]) == 0)         return GL_TRUE;   return GL_FALSE;}/** * Assemble a function call, given a particular function name. * \param name  the function's name (operators like '*' are possible). */static slang_ir_node *_slang_gen_function_call_name(slang_assemble_ctx *A, const char *name,                              slang_operation *oper, slang_operation *dest){   slang_operation *params = oper->children;   const GLuint param_count = oper->num_children;   slang_atom atom;   slang_function *fun;   GLboolean error;   slang_ir_node *n;   atom = slang_atom_pool_atom(A->atoms, name);   if (atom == SLANG_ATOM_NULL)      return NULL;   /*    * First, try to find function by name and exact argument type matching.    */   fun = _slang_locate_function(A->space.funcs, atom, params, param_count,				&A->space, A->atoms, A->log, &error);   if (error) {      slang_info_log_error(A->log,                           "Function '%s' not found (check argument types)",                           name);      return NULL;   }   if (!fun) {      /* Next, try locating a constructor function for a user-defined type */      fun = _slang_locate_struct_constructor(A, name);   }   /*    * At this point, some heuristics are used to try to find a function    * that matches the calling signature by means of casting or "unrolling"    * of constructors.    */   if (!fun && _slang_is_vec_mat_type(name)) {      /* Next, if this call looks like a vec() or mat() constructor call,       * try "unwinding" the args to satisfy a constructor.       */      fun = _slang_find_function_by_max_argc(A->space.funcs, name);      if (fun) {         if (!_slang_adapt_call(oper, fun, &A->space, A->atoms, A->log)) {            slang_info_log_error(A->log,                                 "Function '%s' not found (check argument types)",                                 name);            return NULL;         }      }   }   if (!fun && _slang_is_vec_mat_type(name)) {      /* Next, try casting args to the types of the formal parameters */      int numArgs = oper->num_children;      fun = _slang_find_function_by_argc(A->space.funcs, name, numArgs);      if (!fun || !_slang_cast_func_params(oper, fun, &A->space, A->atoms, A->log)) {         slang_info_log_error(A->log,                              "Function '%s' not found (check argument types)",                              name);         return NULL;      }      assert(fun);   }   if (!fun) {      slang_info_log_error(A->log,                           "Function '%s' not found (check argument types)",                           name);      return NULL;   }   n = _slang_gen_function_call(A, fun, oper, dest);   if (n && !n->Store && !dest       && fun->header.type.specifier.type != SLANG_SPEC_VOID) {      /* setup n->Store for the result of the function call */      GLint size = _slang_sizeof_type_specifier(&fun->header.type.specifier);      n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size);      /*printf("Alloc storage for function result, size %d \n", size);*/   }   return n;}static GLboolean_slang_is_constant_cond(const slang_operation *oper, GLboolean *value){   if (oper->type == SLANG_OPER_LITERAL_FLOAT ||       oper->type == SLANG_OPER_LITERAL_INT ||       oper->type == SLANG_OPER_LITERAL_BOOL) {      if (oper->literal[0])         *value = GL_TRUE;      else         *value = GL_FALSE;      return GL_TRUE;   }   else if (oper->type == SLANG_OPER_EXPRESSION &&            oper->num_children == 1) {      return _slang_is_constant_cond(&oper->children[0], value);   }   return GL_FALSE;}/** * Test if an operation is a scalar or boolean. */static GLboolean_slang_is_scalar_or_boolean(slang_assemble_ctx *A, slang_operation *oper){   slang_typeinfo type;   GLint size;   slang_typeinfo_construct(&type);   _slang_typeof_operation(A, oper, &type);   size = _slang_sizeof_type_specifier(&type.spec);   slang_typeinfo_destruct(&type);   return size == 1;}/** * Test if an operation is boolean. */static GLboolean_slang_is_boolean(slang_assemble_ctx *A, slang_operation *oper){   slang_typeinfo type;   GLboolean isBool;   slang_typeinfo_construct(&type);   _slang_typeof_operation(A, oper, &type);   isBool = (type.spec.type == SLANG_SPEC_BOOL);   slang_typeinfo_destruct(&type);   return isBool;}/** * Generate loop code using high-level IR_LOOP instruction */static slang_ir_node *_slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper){   /*    * LOOP:    *    BREAK if !expr (child[0])    *    body code (child[1])    */   slang_ir_node *prevLoop, *loop, *breakIf, *body;   GLboolean isConst, constTrue;   /* type-check expression */   if (!_slang_is_boolean(A, &oper->children[0])) {      slang_info_log_error(A->log, "scalar/boolean expression expected for 'while'");      return NULL;   }   /* Check if loop condition is a constant */   isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);   if (isConst && !constTrue) {      /* loop is never executed! */      return new_node0(IR_NOP);   }   loop = new_loop(NULL);   /* save old, push new loop */   prevLoop = A->CurLoop;   A->CurLoop = loop;   if (isConst && constTrue) {      /* while(nonzero constant), no conditional break */      breakIf = NULL;   }   else {      slang_ir_node *cond         = new_cond(new_not(_slang_gen_operation(A, &oper->children[0])));      breakIf = new_break_if_true(A->CurLoop, cond);   }   body = _slang_gen_operation(A, &oper->children[1]);   loop->Children[0] = new_seq(breakIf, body);   /* Do infinite loop detection */   /* loop->List is head of linked list of break/continue nodes */   if (!loop->List && isConst && constTrue) {      /* infinite loop detected */      A->CurLoop = prevLoop; /* clean-up */      slang_info_log_error(A->log, "Infinite loop detected!");      return NULL;   }   /* pop loop, restore prev */   A->CurLoop = prevLoop;   return loop;}/** * Generate IR tree for a do-while loop using high-level LOOP, IF instructions. */static slang_ir_node *_slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper){   /*    * LOOP:    *    body code (child[0])    *    tail code:    *       BREAK if !expr (child[1])    */   slang_ir_node *prevLoop, *loop;   GLboolean isConst, constTrue;   /* type-check expression */   if (!_slang_is_boolean(A, &oper->children[1])) {      slang_info_log_error(A->log, "scalar/boolean expression expected for 'do/while'");      return NULL;   }   loop = new_loop(NULL);   /* save old, push new loop */   prevLoop = A->CurLoop;   A->CurLoop = loop;   /* loop body: */   loop->Children[0] = _slang_gen_operation(A, &oper->children[0]);   /* Check if loop condition is a constant */   isConst = _slang_is_constant_cond(&oper->children[1], &constTrue);   if (isConst && constTrue) {      /* do { } while(1)   ==> no conditional break */      loop->Children[1] = NULL; /* no tail code */   }   else {      slang_ir_node *cond         = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));      loop->Children[1] = new_break_if_true(A->CurLoop, cond);   }   /* XXX we should do infinite loop detection, as above */   /* pop loop, restore prev */   A->CurLoop = prevLoop;   return loop;}/** * Generate for-loop using high-level IR_LOOP instruction. */static slang_ir_node *_slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper){   /*    * init code (child[0])    * LOOP:    *    BREAK if !expr (child[1])    *    body code (child[3])    *    tail code:    *       incr code (child[2])   // XXX continue here    */   slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body, *init, *incr;   init = _slang_gen_operation(A, &oper->children[0]);   loop = new_loop(NULL);   /* save old, push new loop */   prevLoop = A->CurLoop;   A->CurLoop = loop;   cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));   breakIf = new_break_if_true(A->CurLoop, cond);   body = _slang_gen_operation(A, &oper->children[3]);   incr = _slang_gen_operation(A, &oper->children[2]);   loop->Children[0] = new_seq(breakIf, body);   loop->Children[1] = incr;  /* tail code */   /* pop loop, restore prev */   A->CurLoop = prevLoop;   return new_seq(init, loop);}static slang_ir_node *_slang_gen_continue(slang_assemble_ctx * A, const slang_operation *oper){   slang_ir_node *n, *loopNode;   assert(oper->type == SLANG_OPER_CONTINUE);   loopNode = A->CurLoop;   assert(loopNode);   assert(loopNode->Opcode == IR_LOOP);   n = new_node0(IR_CONT);   if (n) {      n->Parent = loopNode;      /* insert this node at head of linked list */      n->List = loopNode->List;      loopNode->List = n;   }   return n;}/** * Determine if the given operation is of a specific type. */static GLbooleanis_operation_type(const slang_operation *oper, slang_operation_type type){   if (oper->type == type)      return GL_TRUE;   else if ((oper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||             oper->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) &&            oper->num_children == 1)      return is_operation_type(&oper->children[0], type);   else      return GL_FALSE;}/** * Generate IR tree for an if/then/else conditional using high-level

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -