@@ -2044,20 +2044,17 @@ RuntimeOptimizer::optimize_ops (int beginop, int endop,
20442044 for (int opnum = beginop; opnum < endop; opnum += 1 ) {
20452045 ASSERT (old_num_ops == num_ops); // better not happen unknowingly
20462046 DASSERT (num_ops == inst ()->ops ().size ());
2047+ DASSERT (size_t (opnum) < inst ()->ops ().size ());
20472048 if (m_stop_optimizing)
20482049 break ;
2049- // Before getting a reference to this op, be sure that a space
2050- // is reserved at the end in case a folding routine inserts an
2051- // op. That ensures that the reference won't be invalid.
2052- inst ()->ops ().reserve (num_ops+1 );
2053- Opcode &op (inst ()->ops ()[opnum]);
2050+ Opcode *op = &inst ()->ops ()[opnum];
20542051 if (skipops) {
20552052 // If a previous optimization inserted ops and told us
20562053 // to skip over the new ones, we still need to unalias
20572054 // any symbols written by this op, but otherwise skip
20582055 // all subsequent optimizations until we run down the
20592056 // skipops counter.
2060- block_unalias_written_args (op);
2057+ block_unalias_written_args (* op);
20612058 ASSERT (lastblock == m_bblockids[opnum] &&
20622059 " this should not be a new basic block" );
20632060 --skipops;
@@ -2071,31 +2068,31 @@ RuntimeOptimizer::optimize_ops (int beginop, int endop,
20712068 lastblock = m_bblockids[opnum];
20722069 }
20732070 // Nothing below here to do for no-ops, take early out.
2074- if (op. opname () == u_nop)
2071+ if (op-> opname () == u_nop)
20752072 continue ;
20762073 // De-alias the readable args to the op and figure out if
20772074 // there are any constants involved.
2078- for (int i = 0 , e = op. nargs (); i < e; ++i) {
2079- if (! op. argwrite (i)) { // Don't de-alias args that are written
2080- int argindex = op. firstarg () + i;
2075+ for (int i = 0 , e = op-> nargs (); i < e; ++i) {
2076+ if (! op-> argwrite (i)) { // Don't de-alias args that are written
2077+ int argindex = op-> firstarg () + i;
20812078 int argsymindex = dealias_symbol (inst ()->arg (argindex), opnum);
20822079 inst ()->args ()[argindex] = argsymindex;
20832080 }
2084- if (op. argread (i))
2085- use_stale_sym (oparg (op,i));
2081+ if (op-> argread (i))
2082+ use_stale_sym (oparg (* op,i));
20862083 }
20872084 // If it's a simple assignment and the lvalue is "stale", go
20882085 // back and eliminate its last assignment.
2089- if (is_simple_assign (op))
2090- simple_sym_assign (oparg (op, 0 ), opnum);
2086+ if (is_simple_assign (* op))
2087+ simple_sym_assign (oparg (* op, 0 ), opnum);
20912088 // Make sure there's room for several more symbols, so that we
20922089 // can add a few consts if we need to, without worrying about
20932090 // the addresses of symbols changing when we add a new one below.
20942091 make_symbol_room (max_new_consts_per_fold);
20952092 // For various ops that we know how to effectively
20962093 // constant-fold, dispatch to the appropriate routine.
20972094 if (optimize () >= 2 && m_opt_constant_fold) {
2098- const OpDescriptor *opd = shadingsys ().op_descriptor (op. opname ());
2095+ const OpDescriptor *opd = shadingsys ().op_descriptor (op-> opname ());
20992096 if (opd && opd->folder ) {
21002097 int c = (*opd->folder ) (*this , opnum);
21012098 if (c) {
@@ -2105,23 +2102,24 @@ RuntimeOptimizer::optimize_ops (int beginop, int endop,
21052102 skipops = num_ops - old_num_ops;
21062103 endop += num_ops - old_num_ops; // adjust how far we loop
21072104 old_num_ops = num_ops;
2105+ op = &inst ()->ops ()[opnum]; // in case ops resized
21082106 }
21092107 }
21102108 }
21112109 // Clear local block aliases for any args that were written
21122110 // by this op
2113- block_unalias_written_args (op);
2111+ block_unalias_written_args (* op);
21142112
21152113 // Now we handle assignments.
2116- if (optimize () >= 2 && op. opname () == u_assign && m_opt_assign)
2117- changed += optimize_assignment (op, opnum);
2114+ if (optimize () >= 2 && op-> opname () == u_assign && m_opt_assign)
2115+ changed += optimize_assignment (* op, opnum);
21182116 if (optimize () >= 2 && m_opt_elide_useless_ops)
2119- changed += useless_op_elision (op, opnum);
2117+ changed += useless_op_elision (* op, opnum);
21202118 if (m_stop_optimizing)
21212119 break ;
21222120 // Peephole optimization involving pair of instructions (the second
21232121 // instruction will be in the same basic block.
2124- if (optimize () >= 2 && m_opt_peephole && op. opname () != u_nop) {
2122+ if (optimize () >= 2 && m_opt_peephole && op-> opname () != u_nop) {
21252123 // Find the next instruction in the same basic block
21262124 int op2num = next_block_instruction (opnum);
21272125 if (op2num) {
@@ -2133,21 +2131,22 @@ RuntimeOptimizer::optimize_ops (int beginop, int endop,
21332131 // skipops = num_ops - old_num_ops;
21342132 endop += num_ops - old_num_ops; // adjust how far we loop
21352133 old_num_ops = num_ops;
2134+ op = &inst ()->ops ()[opnum]; // in case ops resized
21362135 }
21372136 }
21382137 }
21392138
21402139 // Special cases for "if", "functioncall", and loops: Optimize the
21412140 // sequences of instructions in the bodies recursively in a way that
21422141 // allows us to be clever about the basic block alias tracking.
2143- ustring opname = op. opname ();
2142+ ustring opname = op-> opname ();
21442143 if ((opname == u_if || opname == u_functioncall ||
21452144 opname == u_for || opname == u_while || opname == u_dowhile)
21462145 && shadingsys ().m_opt_seed_bblock_aliases ) {
21472146 // Find all symbols written anywhere in the instruction range
21482147 // of the bodies.
21492148 FastIntSet symwrites;
2150- catalog_symbol_writes (opnum+1 , op. farthest_jump (), symwrites);
2149+ catalog_symbol_writes (opnum+1 , op-> farthest_jump (), symwrites);
21512150 // Save the aliases from the basic block we are exiting.
21522151 // If & function call: save all prior aliases.
21532152 // Loops: dont save aliases involving syms written in the loop.
@@ -2163,11 +2162,11 @@ RuntimeOptimizer::optimize_ops (int beginop, int endop,
21632162 // one (the body), loops have 4 (init, cond, body, incr),
21642163 int njumps = (opname == u_if) ? 2 : (opname == u_functioncall ? 1 : 4 );
21652164 // Recursively optimize each body block.
2166- // Don't use op after inserstions! Use inst()->op(opnum).
2167- for ( int j = 0 ; j < njumps; ++j)
2168- changed += optimize_ops (j== 0 ? opnum+ 1 : inst ()-> op (opnum). jump (j- 1 ),
2169- inst ()->op (opnum). jump (j),
2170- &saved_block_aliases);
2165+ for ( int j = 0 ; j < njumps; ++j) {
2166+ changed += optimize_ops (j== 0 ? opnum+ 1 : op-> jump (j- 1 ),
2167+ op-> jump (j), &saved_block_aliases);
2168+ op = & inst ()->ops ()[opnum]; // in case ops resized
2169+ }
21712170 // Adjust optimization loop end if any instructions were added
21722171 num_ops = inst ()->ops ().size ();
21732172 endop += num_ops - old_num_ops;
@@ -2182,13 +2181,13 @@ RuntimeOptimizer::optimize_ops (int beginop, int endop,
21822181 restored_aliases.swap (saved_block_aliases);
21832182 // catalog again, in case optimizations in those blocks
21842183 // caused writes that weren't apparent before.
2185- catalog_symbol_writes (opnum+1 , inst ()-> op (opnum). farthest_jump (), symwrites);
2184+ catalog_symbol_writes (opnum+1 , op-> farthest_jump (), symwrites);
21862185 copy_block_aliases (restored_aliases, saved_block_aliases,
21872186 &symwrites);
21882187 }
21892188 seed_block_aliases = &saved_block_aliases;
21902189 // Get ready to increment to the next instruction
2191- opnum = inst ()-> op (opnum). farthest_jump () - 1 ;
2190+ opnum = op-> farthest_jump () - 1 ;
21922191 }
21932192 }
21942193 m_block_aliases_stack.pop_back (); // Done with saved_block_aliases
0 commit comments