本文整理汇总了C++中SymbolPtr::firstuse方法的典型用法代码示例。如果您正苦于以下问题:C++ SymbolPtr::firstuse方法的具体用法?C++ SymbolPtr::firstuse怎么用?C++ SymbolPtr::firstuse使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SymbolPtr
的用法示例。
在下文中一共展示了SymbolPtr::firstuse方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ASSERT
/// Called after code is generated, this function loops over all the ops
/// and figures out the lifetimes of all variables, based on whether the
/// args in each op are read or written.
void
OSLCompilerImpl::track_variable_lifetimes (const OpcodeVec &code,
const SymbolPtrVec &opargs,
const SymbolPtrVec &allsyms,
std::vector<int> *bblockids)
{
// Clear the lifetimes for all symbols
BOOST_FOREACH (Symbol *s, allsyms)
s->clear_rw ();
// Keep track of the nested loops we're inside. We track them by pairs
// of begin/end instruction numbers for that loop body, including
// conditional evaluation (skip the initialization). Note that the end
// is inclusive. We use this vector of ranges as a stack.
typedef std::pair<int,int> intpair;
std::vector<intpair> loop_bounds;
// For each op, mark its arguments as being used at that op
int opnum = 0;
BOOST_FOREACH (const Opcode &op, code) {
if (op.opname() == op_for || op.opname() == op_while ||
op.opname() == op_dowhile) {
// If this is a loop op, we need to mark its control variable
// (the only arg) as used for the duration of the loop!
ASSERT (op.nargs() == 1); // loops should have just one arg
SymbolPtr s = opargs[op.firstarg()];
int loopcond = op.jump (0); // after initialization, before test
int loopend = op.farthest_jump() - 1; // inclusive end
s->mark_rw (opnum+1, true, true);
s->mark_rw (loopend, true, true);
// Also push the loop bounds for this loop
loop_bounds.push_back (std::make_pair(loopcond, loopend));
}
// Some work to do for each argument to the op...
for (int a = 0; a < op.nargs(); ++a) {
SymbolPtr s = opargs[op.firstarg()+a];
ASSERT (s->dealias() == s); // Make sure it's de-aliased
// Mark that it's read and/or written for this op
bool readhere = op.argread(a);
bool writtenhere = op.argwrite(a);
s->mark_rw (opnum, readhere, writtenhere);
// Adjust lifetimes of symbols whose values need to be preserved
// between loop iterations.
BOOST_FOREACH (intpair oprange, loop_bounds) {
int loopcond = oprange.first;
int loopend = oprange.second;
DASSERT (s->firstuse() <= loopend);
// Special case: a temp or local, even if written inside a
// loop, if it's entire lifetime is within one basic block
// and it's strictly written before being read, then its
// lifetime is truly local and doesn't need to be expanded
// for the duration of the loop.
if (bblockids &&
(s->symtype()==SymTypeLocal || s->symtype()==SymTypeTemp) &&
(*bblockids)[s->firstuse()] == (*bblockids)[s->lastuse()] &&
s->lastwrite() < s->firstread()) {
continue;
}
// Syms written before or inside the loop, and referenced
// inside or after the loop, need to preserve their value
// for the duration of the loop. We know it's referenced
// inside the loop because we're here examining it!
if (s->firstwrite() <= loopend) {
s->mark_rw (loopcond, readhere, writtenhere);
s->mark_rw (loopend, readhere, writtenhere);
}
}
}
++opnum; // Advance to the next op index
// Pop any loop bounds for loops we've just exited
while (!loop_bounds.empty() && loop_bounds.back().second < opnum)
loop_bounds.pop_back ();
}