virtual void visit(ir_barrier *);
/*@}*/
+ void visit_expression(ir_expression *, st_src_reg *) ATTRIBUTE_NOINLINE;
+
void visit_atomic_counter_intrinsic(ir_call *);
void visit_ssbo_intrinsic(ir_call *);
void visit_membar_intrinsic(ir_call *);
void
glsl_to_tgsi_visitor::visit(ir_expression *ir)
{
- unsigned int operand;
st_src_reg op[ARRAY_SIZE(ir->operands)];
- st_src_reg result_src;
- st_dst_reg result_dst;
/* Quick peephole: Emit MAD(a, b, c) instead of ADD(MUL(a, b), c)
*/
if (ir->operation == ir_quadop_vector)
assert(!"ir_quadop_vector should have been lowered");
- for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ for (unsigned int operand = 0; operand < ir->get_num_operands(); operand++) {
this->result.file = PROGRAM_UNDEFINED;
ir->operands[operand]->accept(this);
if (this->result.file == PROGRAM_UNDEFINED) {
assert(!ir->operands[operand]->type->is_matrix());
}
+ visit_expression(ir, op);
+}
+
+/* The non-recursive part of the expression visitor lives in a separate
+ * function and should be prevented from being inlined, to avoid a stack
+ * explosion when deeply nested expressions are visited.
+ */
+void
+glsl_to_tgsi_visitor::visit_expression(ir_expression* ir, st_src_reg *op)
+{
+ st_src_reg result_src;
+ st_dst_reg result_dst;
+
int vector_elements = ir->operands[0]->type->vector_elements;
if (ir->operands[1]) {
vector_elements = MAX2(vector_elements,
#define MUST_CHECK
#endif
+#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+#define ATTRIBUTE_NOINLINE __attribute__((noinline))
+#else
+#define ATTRIBUTE_NOINLINE
+#endif
+
/** Compute ceiling of integer quotient of A divided by B. */
#define DIV_ROUND_UP( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )