本文整理汇总了C++中SymbolPtr::mark_rw方法的典型用法代码示例。如果您正苦于以下问题:C++ SymbolPtr::mark_rw方法的具体用法?C++ SymbolPtr::mark_rw怎么用?C++ SymbolPtr::mark_rw使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SymbolPtr
的用法示例。
在下文中一共展示了SymbolPtr::mark_rw方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: op_for
/// 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)
{
// Clear the lifetimes for all symbols
BOOST_FOREACH (Symbol *s, allsyms)
s->clear_rw ();
static ustring op_for("for");
static ustring op_while("while");
static ustring op_dowhile("dowhile");
// For each op, mark its arguments as being used at that op
int opnum = 0;
BOOST_FOREACH (const Opcode &op, code) {
// 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);
// s = s->dealias(); // Make sure it's de-aliased
// Mark that it's read and/or written for this op
s->mark_rw (opnum, op.argread(a), op.argwrite(a));
}
// If this is a loop op, we need to mark its control variable
// (the only arg) as used for the duration of the loop!
if (op.opname() == op_for ||
op.opname() == op_while ||
op.opname() == op_dowhile) {
ASSERT (op.nargs() == 1); // loops should have just one arg
SymbolPtr s = opargs[op.firstarg()];
s->mark_rw (opnum+1, true, true);
s->mark_rw (op.farthest_jump()-1, true, true);
}
++opnum;
}
// Special cases: handle variables whose lifetimes cross the boundaries
// of a loop.
opnum = 0;
BOOST_FOREACH (const Opcode &op, code) {
if (op.opname() == op_for ||
op.opname() == op_while ||
op.opname() == op_dowhile) {
int loopcond = op.jump (0); // after initialization, before test
int loopend = op.farthest_jump() - 1;
BOOST_FOREACH (Symbol *s, allsyms) {
// Temporaries referenced both inside AND outside a loop
// need their lifetimes extended to cover the entire
// loop so they aren't coalesced incorrectly. The
// specific danger is for a function that contains a
// loop, and the function is passed an argument that is
// a temporary calculation.
if (s->symtype() == SymTypeTemp &&
((s->firstuse() < loopcond && s->lastuse() >= loopcond) ||
(s->firstuse() < loopend && s->lastuse() >= loopend))) {
s->mark_rw (opnum, true, true);
s->mark_rw (loopend, true, true);
}
// Locals that are written within the loop should have
// their usage conservatively expanded to the whole
// loop. This is not a worry for temps, because they
// CAN'T be read in the next iteration unless they were
// set before the loop, handled above. Ideally, we
// could be less conservative if we knew that the
// variable in question was declared/scoped internal to
// the loop, in which case it can't carry values to the
// next iteration (FIXME).
if (s->symtype() == SymTypeLocal &&
s->firstuse() < loopend && s->lastwrite() >= loopcond) {
bool read = (s->lastread() >= loopcond);
s->mark_rw (opnum, read, true);
s->mark_rw (loopend, read, true);
}
}
}
++opnum;
}
示例2: op_for
/// 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)
{
// Clear the lifetimes for all symbols
BOOST_FOREACH (Symbol *s, allsyms)
s->clear_rw ();
static ustring op_for("for");
static ustring op_while("while");
static ustring op_dowhile("dowhile");
// For each op, mark its arguments as being used at that op
int opnum = 0;
BOOST_FOREACH (const Opcode &op, code) {
// 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);
// s = s->dealias(); // Make sure it's de-aliased
// Mark that it's read and/or written for this op
s->mark_rw (opnum, op.argread(a), op.argwrite(a));
}
// If this is a loop op, we need to mark its control variable
// (the only arg) as used for the duration of the loop!
if (op.opname() == op_for ||
op.opname() == op_while ||
op.opname() == op_dowhile) {
ASSERT (op.nargs() == 1); // loops should have just one arg
SymbolPtr s = opargs[op.firstarg()];
s->mark_rw (opnum+1, true, true);
s->mark_rw (op.farthest_jump()-1, true, true);
}
++opnum;
}
// Special case: temporaries referenced both inside AND outside a
// loop need their lifetimes extended to cover the entire loop so
// they aren't accidentally coalesced incorrectly. The specific
// danger is for a function that contains a loop, and the function
// is passed an argument that is a temporary calculation.
opnum = 0;
BOOST_FOREACH (const Opcode &op, code) {
if (op.opname() == op_for ||
op.opname() == op_while ||
op.opname() == op_dowhile) {
int loopend = op.farthest_jump() - 1;
BOOST_FOREACH (Symbol *s, allsyms) {
if (s->symtype() == SymTypeTemp &&
((s->firstuse() < opnum && s->lastuse() >= opnum) ||
(s->firstuse() < loopend && s->lastuse() >= loopend))) {
s->mark_rw (opnum, true, true);
s->mark_rw (loopend, true, true);
}
}
}
++opnum;
}
示例3: 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 ();
}