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

📄 slang_codegen.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
   { "float_cosine", IR_COS, 1, 1 },   { "float_noise1", IR_NOISE1, 1, 1},   { "float_noise2", IR_NOISE2, 1, 1},   { "float_noise3", IR_NOISE3, 1, 1},   { "float_noise4", IR_NOISE4, 1, 1},   { NULL, IR_NOP, 0, 0 }};static slang_ir_node *new_node3(slang_ir_opcode op,          slang_ir_node *c0, slang_ir_node *c1, slang_ir_node *c2){   slang_ir_node *n = (slang_ir_node *) _slang_alloc(sizeof(slang_ir_node));   if (n) {      n->Opcode = op;      n->Children[0] = c0;      n->Children[1] = c1;      n->Children[2] = c2;      n->Writemask = WRITEMASK_XYZW;      n->InstLocation = -1;   }   return n;}static slang_ir_node *new_node2(slang_ir_opcode op, slang_ir_node *c0, slang_ir_node *c1){   return new_node3(op, c0, c1, NULL);}static slang_ir_node *new_node1(slang_ir_opcode op, slang_ir_node *c0){   return new_node3(op, c0, NULL, NULL);}static slang_ir_node *new_node0(slang_ir_opcode op){   return new_node3(op, NULL, NULL, NULL);}/** * Create sequence of two nodes. */static slang_ir_node *new_seq(slang_ir_node *left, slang_ir_node *right){   if (!left)      return right;   if (!right)      return left;   return new_node2(IR_SEQ, left, right);}static slang_ir_node *new_label(slang_label *label){   slang_ir_node *n = new_node0(IR_LABEL);   assert(label);   if (n)      n->Label = label;   return n;}static slang_ir_node *new_float_literal(const float v[4], GLuint size){   slang_ir_node *n = new_node0(IR_FLOAT);   assert(size <= 4);   COPY_4V(n->Value, v);   /* allocate a storage object, but compute actual location (Index) later */   n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);   return n;}static slang_ir_node *new_not(slang_ir_node *n){   return new_node1(IR_NOT, n);}/** * Non-inlined function call. */static slang_ir_node *new_function_call(slang_ir_node *code, slang_label *name){   slang_ir_node *n = new_node1(IR_CALL, code);   assert(name);   if (n)      n->Label = name;   return n;}/** * Unconditional jump. */static slang_ir_node *new_return(slang_label *dest){   slang_ir_node *n = new_node0(IR_RETURN);   assert(dest);   if (n)      n->Label = dest;   return n;}static slang_ir_node *new_loop(slang_ir_node *body){   return new_node1(IR_LOOP, body);}static slang_ir_node *new_break(slang_ir_node *loopNode){   slang_ir_node *n = new_node0(IR_BREAK);   assert(loopNode);   assert(loopNode->Opcode == IR_LOOP);   if (n) {      /* insert this node at head of linked list */      n->List = loopNode->List;      loopNode->List = n;   }   return n;}/** * Make new IR_BREAK_IF_TRUE. */static slang_ir_node *new_break_if_true(slang_ir_node *loopNode, slang_ir_node *cond){   slang_ir_node *n;   assert(loopNode);   assert(loopNode->Opcode == IR_LOOP);   n = new_node1(IR_BREAK_IF_TRUE, cond);   if (n) {      /* insert this node at head of linked list */      n->List = loopNode->List;      loopNode->List = n;   }   return n;}/** * Make new IR_CONT_IF_TRUE node. */static slang_ir_node *new_cont_if_true(slang_ir_node *loopNode, slang_ir_node *cond){   slang_ir_node *n;   assert(loopNode);   assert(loopNode->Opcode == IR_LOOP);   n = new_node1(IR_CONT_IF_TRUE, cond);   if (n) {      /* insert this node at head of linked list */      n->List = loopNode->List;      loopNode->List = n;   }   return n;}static slang_ir_node *new_cond(slang_ir_node *n){   slang_ir_node *c = new_node1(IR_COND, n);   return c;}static slang_ir_node *new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart){   return new_node3(IR_IF, cond, ifPart, elsePart);}/** * New IR_VAR node - a reference to a previously declared variable. */static slang_ir_node *new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name){   slang_ir_node *n;   slang_variable *var = _slang_locate_variable(oper->locals, name, GL_TRUE);   if (!var)      return NULL;   assert(var->declared);   assert(!oper->var || oper->var == var);   n = new_node0(IR_VAR);   if (n) {      _slang_attach_storage(n, var);      /*      printf("new_var %s store=%p\n", (char*)name, (void*) n->Store);      */   }   return n;}/** * Check if the given function is really just a wrapper for a * basic assembly instruction. */static GLbooleanslang_is_asm_function(const slang_function *fun){   if (fun->body->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE &&       fun->body->num_children == 1 &&       fun->body->children[0].type == SLANG_OPER_ASM) {      return GL_TRUE;   }   return GL_FALSE;}static GLboolean_slang_is_noop(const slang_operation *oper){   if (!oper ||       oper->type == SLANG_OPER_VOID ||       (oper->num_children == 1 && oper->children[0].type == SLANG_OPER_VOID))      return GL_TRUE;   else      return GL_FALSE;}/** * Recursively search tree for a node of the given type. */static slang_operation *_slang_find_node_type(slang_operation *oper, slang_operation_type type){   GLuint i;   if (oper->type == type)      return oper;   for (i = 0; i < oper->num_children; i++) {      slang_operation *p = _slang_find_node_type(&oper->children[i], type);      if (p)         return p;   }   return NULL;}/** * Count the number of operations of the given time rooted at 'oper'. */static GLuint_slang_count_node_type(slang_operation *oper, slang_operation_type type){   GLuint i, count = 0;   if (oper->type == type) {      return 1;   }   for (i = 0; i < oper->num_children; i++) {      count += _slang_count_node_type(&oper->children[i], type);   }   return count;}/** * Check if the 'return' statement found under 'oper' is a "tail return" * that can be no-op'd.  For example: * * void func(void) * { *    .. do something .. *    return;   // this is a no-op * } * * This is used when determining if a function can be inlined.  If the * 'return' is not the last statement, we can't inline the function since * we still need the semantic behaviour of the 'return' but we don't want * to accidentally return from the _calling_ function.  We'd need to use an * unconditional branch, but we don't have such a GPU instruction (not * always, at least). */static GLboolean_slang_is_tail_return(const slang_operation *oper){   GLuint k = oper->num_children;   while (k > 0) {      const slang_operation *last = &oper->children[k - 1];      if (last->type == SLANG_OPER_RETURN)         return GL_TRUE;      else if (last->type == SLANG_OPER_IDENTIFIER ||               last->type == SLANG_OPER_LABEL)         k--; /* try prev child */      else if (last->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE ||               last->type == SLANG_OPER_BLOCK_NEW_SCOPE)         /* try sub-children */         return _slang_is_tail_return(last);      else         break;   }   return GL_FALSE;}static voidslang_resolve_variable(slang_operation *oper){   if (oper->type == SLANG_OPER_IDENTIFIER && !oper->var) {      oper->var = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE);   }}/** * Replace particular variables (SLANG_OPER_IDENTIFIER) with new expressions. */static voidslang_substitute(slang_assemble_ctx *A, slang_operation *oper,                 GLuint substCount, slang_variable **substOld,		 slang_operation **substNew, GLboolean isLHS){   switch (oper->type) {   case SLANG_OPER_VARIABLE_DECL:      {         slang_variable *v = _slang_locate_variable(oper->locals,                                                    oper->a_id, GL_TRUE);         assert(v);         if (v->initializer && oper->num_children == 0) {            /* set child of oper to copy of initializer */            oper->num_children = 1;            oper->children = slang_operation_new(1);            slang_operation_copy(&oper->children[0], v->initializer);         }         if (oper->num_children == 1) {            /* the initializer */            slang_substitute(A, &oper->children[0], substCount,                             substOld, substNew, GL_FALSE);         }      }      break;   case SLANG_OPER_IDENTIFIER:      assert(oper->num_children == 0);      if (1/**!isLHS XXX FIX */) {         slang_atom id = oper->a_id;         slang_variable *v;	 GLuint i;         v = _slang_locate_variable(oper->locals, id, GL_TRUE);	 if (!v) {            _mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id);            return;	 }	 /* look for a substitution */	 for (i = 0; i < substCount; i++) {	    if (v == substOld[i]) {               /* OK, replace this SLANG_OPER_IDENTIFIER with a new expr */#if 0 /* DEBUG only */	       if (substNew[i]->type == SLANG_OPER_IDENTIFIER) {                  assert(substNew[i]->var);                  assert(substNew[i]->var->a_name);		  printf("Substitute %s with %s in id node %p\n",			 (char*)v->a_name, (char*) substNew[i]->var->a_name,			 (void*) oper);               }	       else {		  printf("Substitute %s with %f in id node %p\n",			 (char*)v->a_name, substNew[i]->literal[0],			 (void*) oper);               }#endif	       slang_operation_copy(oper, substNew[i]);	       break;	    }	 }      }      break;   case SLANG_OPER_RETURN:      /* do return replacement here too */      assert(oper->num_children == 0 || oper->num_children == 1);      if (oper->num_children == 1 && !_slang_is_noop(&oper->children[0])) {         /* replace:          *   return expr;          * with:          *   __retVal = expr;          *   return;          * then do substitutions on the assignment.          */         slang_operation *blockOper, *assignOper, *returnOper;         /* check if function actually has a return type */         assert(A->CurFunction);         if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {            slang_info_log_error(A->log, "illegal return expression");            return;         }         blockOper = slang_operation_new(1);         blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;         blockOper->num_children = 2;         blockOper->locals->outer_scope = oper->locals->outer_scope;         blockOper->children = slang_operation_new(2);         assignOper = blockOper->children + 0;         returnOper = blockOper->children + 1;         assignOper->type = SLANG_OPER_ASSIGN;         assignOper->num_children = 2;         assignOper->locals->outer_scope = blockOper->locals;         assignOper->children = slang_operation_new(2);         assignOper->children[0].type = SLANG_OPER_IDENTIFIER;         assignOper->children[0].a_id = slang_atom_pool_atom(A->atoms, "__retVal");         assignOper->children[0].locals->outer_scope = assignOper->locals;         slang_operation_copy(&assignOper->children[1],                              &oper->children[0]);         returnOper->type = SLANG_OPER_RETURN; /* return w/ no value */         assert(returnOper->num_children == 0);         /* do substitutions on the "__retVal = expr" sub-tree */         slang_substitute(A, assignOper,                          substCount, substOld, substNew, GL_FALSE);         /* install new code */         slang_operation_copy(oper, blockOper);         slang_operation_destruct(blockOper);      }      else {         /* check if return value was expected */         assert(A->CurFunction);         if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {            slang_info_log_error(A->log, "return statement requires an expression");            return;         }      }      break;   case SLANG_OPER_ASSIGN:   case SLANG_OPER_SUBSCRIPT:      /* special case:       * child[0] can't have substitutions but child[1] can.       */      slang_substitute(A, &oper->children[0],

⌨️ 快捷键说明

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