下面列出了org.apache.log4j.Logger#isTraceEnabled ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void placeRefcounts(Logger logger, GlobalVars globals, Function fn,
Block block, RCTracker increments, Set<Var> parentAssignedAliasVars) {
// First canonicalize so we can merge refcounts
increments.canonicalize();
if (logger.isTraceEnabled()) {
logger.trace("");
logger.trace("Adding increments for block " + block.getType() + " of " +
fn.id());
logger.trace("==============================");
logger.trace(increments);
}
reorderContinuations(logger, block);
// Move any increment instructions up to this block
// if they can be combined with increments here
pullUpRefIncrements(block, increments);
placer.placeAll(logger, globals, fn, block, increments,
parentAssignedAliasVars);
}
/**
* Prints out the configuration in sorted order.
*/
public static void printConfig(Configuration conf, Logger log) {
if (log.isTraceEnabled()) {
SortedSet<String> sortedKeys = new TreeSet<>();
for (Map.Entry<String,String> e : conf) {
sortedKeys.add(e.getKey());
}
for (String k : sortedKeys) {
log.trace(k + "=" + conf.get(k));
}
}
}
public void closeConnection(Logger log) {
if (log.isTraceEnabled()) {
log.trace("closing connections for query " + getQueryId());
}
Connection connection = getConnection();
Statement statement = getStatement();
CachedRowSet crs = getCrs();
resetConnection();
DbUtils.closeQuietly(connection, statement, crs);
}
/**
* @param comparable
* @param methodReference
* @return
*/
private boolean isImplied ( Logger cl, MethodReference comparable, MethodReference actual, MethodReference methodReference ) {
Set<MethodReference> alreadyKnown = this.state.getAlreadyKnown(comparable);
for ( MethodReference ref : alreadyKnown ) {
if ( ref.implies(methodReference) ) {
if ( cl.isTraceEnabled() ) {
cl.trace(actual + " implied by " + methodReference); //$NON-NLS-1$
}
return true;
}
}
return false;
}
private synchronized void forceLogLevels() {
Logger bindLog = LogManager.getLogger(org.hibernate.type.descriptor.sql.BasicBinder.class);
if(bindLog != null && !bindLog.isTraceEnabled()) {
restoreBindLevel = bindLog.getLevel();
restoreBind = true;
bindLog.setLevel(Level.TRACE);
}
Logger sqlLog = LogManager.getLogger("org.hibernate.SQL");
if(sqlLog != null && !sqlLog.isDebugEnabled()) {
restoreSQLLevel = sqlLog.getLevel();
restoreSQL = true;
sqlLog.setLevel(Level.DEBUG);
}
Logger statLog = LogManager.getLogger(org.hibernate.stat.StatisticsImpl.class);
if(statLog != null && !statLog.isInfoEnabled()) {
restoreStatLevel = statLog.getLevel();
restoreStat = true;
statLog.setLevel(Level.INFO);
}
Logger loaderLog = LogManager.getLogger(org.hibernate.loader.Loader.class);
if(loaderLog != null && !loaderLog.isTraceEnabled()) { // Trace for hydrated objects, Debug for result row
restoreLoaderLevel = loaderLog.getLevel();
restoreLoader = true;
loaderLog.setLevel(Level.TRACE);
}
Logger jdbcLog = LogManager.getLogger(org.hibernate.jdbc.AbstractBatcher.class);
if(jdbcLog != null && !jdbcLog.isDebugEnabled()) {
restoreJdbcLevel = jdbcLog.getLevel();
restoreJdbc = true;
jdbcLog.setLevel(Level.DEBUG);
}
}
/**
* Return true if inst2 writes some of inst1's required vars
*
* TODO: the current approach can result in false positives, e.g.
* alias instructions look like they're reading variable.
* @param logger
* @param inst1
* @param inst1Inputs
* @param inst2
* @param inst2Inputs
* @return
*/
private boolean writesInputs(Logger logger,
StatementInfo info1,
StatementInfo info2) {
for (Instruction storeRef: info2.getByOpcode(Opcode.STORE_REF)) {
assert(storeRef.op == Opcode.STORE_REF);
if (info1.piecewiseAssigned.contains(storeRef.getOutput(0))) {
// Special case for address_of: otherwise looks like they both write it
if (logger.isTraceEnabled())
logger.trace(info2 + " pieces " + info1);
return true;
}
}
// Check for initialization of outputs (inputs covered by other logic)
if (initializesOutputs(info1, info2)) {
if (logger.isTraceEnabled())
logger.trace(info2 + " initializes output of " + info1);
return true;
}
for (Var inst2Output: info2.modifiedOutputs) {
if (info1.inputVars.contains(inst2Output)) {
if (logger.isTraceEnabled())
logger.trace(info2 + " modifies input of " + info1);
return true;
}
}
return false;
}
/**
* Try to piggyback decrement operations on instructions or continuations
* in block
*
* @param logger
* @param fn
* @param block
* @param tracker
* @param rcType
*/
private void piggybackOnStatements(Logger logger, Function fn,
Block block, RCTracker tracker, RCDir dir, RefCountType rcType) {
if (!RCUtil.piggybackEnabled()) {
return;
}
// Initially all decrements are candidates for piggybacking
RefCountCandidates candidates =
tracker.getVarCandidates(block, rcType, dir);
if (logger.isTraceEnabled()) {
logger.trace("Piggyback candidates: " + candidates);
}
UseFinder subblockWalker = new UseFinder(tracker, rcType,
candidates.varKeySet());
// Depending on whether it's a decrement or an increment, we need
// to traverse statements in a different direciton so that refcounts
// can be disqualified in the right order
boolean reverse = (dir == RCDir.DECR);
if (reverse) {
piggybackOnContinuations(logger, fn, block, tracker, dir, rcType,
candidates, subblockWalker, reverse);
}
piggybackOnStatements(logger, fn, block, tracker, dir, rcType, candidates,
subblockWalker, reverse);
if (!reverse) {
piggybackOnContinuations(logger, fn, block, tracker, dir, rcType,
candidates, subblockWalker, reverse);
}
}
private static void updateCongruent(Logger logger, GlobalConstants consts,
Function function, Instruction inst, int stmtIndex,
Congruences state) throws OptUnsafeError {
List<ValLoc> resVals = inst.getResults();
List<Alias> aliases = inst.getAliases();
if (logger.isTraceEnabled()) {
logger.trace("resVals: " + resVals);
logger.trace("aliases: " + aliases);
}
state.update(consts, function.id().uniqueName(), resVals, aliases,
stmtIndex);
}
public static void trace(Logger logger, String messageFormat,Object...args){
if(logger.isTraceEnabled())logger.trace(String.format(messageFormat,args));
}
/**
* Attempt to explode individual instruction
* @param logger
* @param fn
* @param execCx
* @param block
* @param it
* @param inst
* @param waitedFor any vars waited for, e.g. in outer exploded. This prevents
* infinite cycles of exploding if we didn't change instruction
* @return true if exploded
*/
private static boolean tryExplode(Logger logger, Function fn,
ExecContext execCx, Block block, ListIterator<Statement> it,
Instruction inst, HierarchicalSet<Var> waitedFor) {
MakeImmRequest req = inst.canMakeImmediate(waitedFor,
Collections.<ArgCV>emptySet(), Collections.<Var>emptySet(),
true);
if (req != null && req.in.size() > 0) {
if (logger.isTraceEnabled()) {
logger.trace("Exploding " + inst + " in function " + fn.id());
}
// Remove old instruction now that we're certain to replace it
it.remove();
List<Pair<Var, Ternary>> waitVars = new ArrayList<Pair<Var, Ternary>>();
Map<Var, Var> filenameMap = new HashMap<Var, Var>();
OptUtil.buildWaitVars(block, it, req.in, req.out, filenameMap, waitVars);
Block insideWaitBlock = enterWaits(fn, execCx, block, inst, req, waitVars);
// Instructions to add inside wait
List<Statement> instBuffer = new ArrayList<Statement>();
// Fetch the inputs
List<Arg> inVals = OptUtil.fetchMakeImmInputs(insideWaitBlock, req.in,
instBuffer);
// Create local instruction, copy out outputs
List<Var> localOutputs = OptUtil.createMakeImmOutputs(insideWaitBlock,
req.out, filenameMap, instBuffer);
MakeImmChange change = inst.makeImmediate(
new OptVarCreator(insideWaitBlock),
Fetched.makeList(req.out, localOutputs, true),
Fetched.makeList(req.in, inVals, false));
OptUtil.fixupImmChange(fn.id(), block, insideWaitBlock, inst,
change, instBuffer, localOutputs, req.out);
// Remove old instruction, add new one inside wait block
insideWaitBlock.addStatements(instBuffer);
return true;
}
return false;
}
/**
* Assuming that branches are exhaustive, work out the set of variables
* closed after the conditional has executed.
*
* @param state
* @param branchStates
* @return
* @throws OptUnsafeError
*/
public static UnifiedValues unify(Logger logger, GlobalConstants consts,
Function fn, boolean reorderingAllowed, int parentStmtIndex,
Congruences state, Continuation cont,
List<Congruences> branchStates, List<Block> branchBlocks)
throws OptUnsafeError {
if (logger.isTraceEnabled()) {
logger.trace("Unifying state from " + branchBlocks.size() +
" branches with continuation type " + cont.getType());
for (int i = 0; i < branchBlocks.size(); i++) {
logger.trace("Branch " + (i + 1) + " type was " +
branchBlocks.get(i).getType());
}
}
if (branchStates.isEmpty()) {
return EMPTY;
} else {
Set<Var> closed = new HashSet<Var>();
Set<Var> recClosed = new HashSet<Var>();
unifyClosed(branchStates, closed, recClosed, parentStmtIndex);
List<ValLoc> availVals = new ArrayList<ValLoc>();
List<ArgCV> allUnifiedCVs = new ArrayList<ArgCV>();
// Track which sets of args from each branch are mapped into a
// unified var
Map<List<Arg>, Var> unifiedVars = new HashMap<List<Arg>, Var>();
int iter = 1;
boolean newCVs;
do {
if (logger.isTraceEnabled()) {
logger.trace("Start iteration " + iter + " of unification");
}
newCVs = false;
for (CongruenceType congType: Arrays.asList(CongruenceType.VALUE,
CongruenceType.ALIAS)) {
List<ArgCV> newAllBranchCVs = findAllBranchCVs(state, congType,
branchStates, allUnifiedCVs);
Pair<List<ValLoc>, Boolean> result = unifyCVs(consts, fn,
reorderingAllowed, cont.parent(), parentStmtIndex, congType,
branchStates, branchBlocks, newAllBranchCVs, unifiedVars);
availVals.addAll(result.val1);
if (result.val2) {
newCVs = true;
}
allUnifiedCVs.addAll(newAllBranchCVs);
if (logger.isTraceEnabled()) {
logger.trace("Finish iteration " + iter + " of unification for "
+ congType + " New CVs: " + result.val1);
}
}
if (iter >= MAX_UNIFY_ITERATIONS) {
logger.debug("Exceeded max unify iterations.");
if (logger.isTraceEnabled()) {
logger.trace(cont); // Dump IR for inspection
}
break;
}
iter++;
} while (newCVs);
return new UnifiedValues(closed, recClosed, availVals);
}
}
private void structBuildRec(Logger logger, Block block) {
// Track all assigned struct paths
ListMultimap<Var, List<String>> assignedPaths = ArrayListMultimap.create();
// Find all struct assign statements in block
for (Statement stmt: block.getStatements()) {
if (stmt.type() == StatementType.INSTRUCTION) {
Instruction inst = stmt.instruction();
if (inst.op == Opcode.STRUCT_STORE_SUB) {
Var struct = inst.getOutput(0);
List<Arg> inputs = inst.getInputs();
List<Arg> fields = inputs.subList(1, inputs.size());
assignedPaths.put(struct, Arg.extractStrings(fields));
}
}
}
// Check if all fields were assigned
for (Var candidate: assignedPaths.keySet()) {
StructType candidateType = (StructType)candidate.type().getImplType();
Set<List<String>> expectedPaths = allAssignablePaths(candidateType);
List<List<String>> assigned = assignedPaths.get(candidate);
logger.trace("Check candidate " + candidate.name() + "\n" +
"expected: " + expectedPaths + "\n" +
"assigned: " + assigned);
for (List<String> path: assigned) {
Type fieldType;
try {
fieldType = candidateType.fieldTypeByPath(path);
} catch (TypeMismatchException e) {
throw new STCRuntimeError(e.getMessage());
}
Set<List<String>> assignedSubPaths;
if (Types.isStruct(fieldType)) {
// Handle case where we assign a substruct
StructType structFieldType = (StructType)fieldType.getImplType();
assignedSubPaths = allAssignablePaths(structFieldType, path);
} else {
assignedSubPaths = Collections.singleton(path);
}
for (List<String> assignedPath: assignedSubPaths) {
boolean found = expectedPaths.remove(assignedPath);
if (!found) {
logger.warn("Invalid or double-assigned struct field: " +
candidate.name() + "." + assignedPath);
}
}
}
if (expectedPaths.isEmpty()) {
doStructBuildTransform(logger, block, candidate, assigned.size());
} else if (logger.isTraceEnabled()) {
logger.trace("Fields not assigned: " + expectedPaths);
}
}
for (Continuation cont: block.allComplexStatements()) {
for (Block cb: cont.getBlocks()) {
structBuildRec(logger, cb);
}
}
}
private void piggybackOnStatements(Logger logger, Function fn, Block block,
RCTracker tracker, RCDir dir, RefCountType rcType,
RefCountCandidates candidates, UseFinder subblockWalker, boolean reverse) {
// Vars where we were successful
List<VarCount> successful = new ArrayList<VarCount>();
// scan up from bottom of block instructions to see if we can piggyback
ListIterator<Statement> it = reverse ? block.statementEndIterator()
: block.statementIterator();
while ((reverse && it.hasPrevious()) || (!reverse && it.hasNext())) {
Statement stmt;
if (reverse) {
stmt = it.previous();
} else {
stmt = it.next();
}
switch (stmt.type()) {
case INSTRUCTION: {
Instruction inst = stmt.instruction();
if (logger.isTraceEnabled()) {
logger.trace("Try piggyback " + dir + " on " + inst);
}
VarCount piggybacked;
do {
/* Process one at a time so that candidates is correctly updated
* for each call based on previous changes */
piggybacked = inst.tryPiggyback(candidates, rcType);
if (piggybacked != null && piggybacked.count != 0) {
if (logger.isTraceEnabled()) {
logger.trace("Piggybacked decr " + piggybacked + " on " + inst);
}
candidates.add(piggybacked.var, -piggybacked.count);
successful.add(piggybacked);
}
} while (piggybacked != null && piggybacked.count != 0);
// Make sure we don't modify before a use of the var by removing
// from candidate set
List<Var> used = findUses(inst, tracker, rcType,
candidates.varKeySet());
removeCandidates(used, tracker, candidates);
break;
}
case CONDITIONAL:
// Walk continuation to find usages
subblockWalker.reset();
TreeWalk.walkSyncChildren(logger, fn, stmt.conditional(), subblockWalker);
removeCandidates(subblockWalker.getUsedVars(), tracker, candidates);
break;
default:
throw new STCRuntimeError("Unknown statement type " + stmt.type());
}
}
if (logger.isTraceEnabled()) {
logger.trace(successful);
}
// Update main increments map
for (VarCount vc: successful) {
assert(vc != null);
tracker.cancel(tracker.getRefCountVar(vc.var), rcType, -vc.count);
}
}
private void optRecurseOnBlock(Logger logger, Function f, Block block,
ArrayInfo info, InitState init,
HierarchicalSet<Var> cands, HierarchicalSet<Var> invalid) {
addBlockCandidates(f, block, info, cands);
for (Var cand: cands) {
if (!invalid.contains(cand)) {
AliasTracker blockAliases = info.getAliases(block);
AliasKey candKey = blockAliases.getCanonical(cand);
BlockVarInfo vi = info.getEntry(block, cand);
if (logger.isTraceEnabled()) {
logger.trace("Candidate: " + cand + " in block " +
System.identityHashCode(block) + " " + block.getType());
logger.trace(vi);
}
if (vi.otherModRec) {
logger.trace("Can't optimize due to other inserts!");
invalid.add(cand);
} else if ((vi.insertImmOnce && vi.insertImmHere) ||
(vi.noInserts() && vi.declaredHere)) {
// Criteria 1: declared here && no inserts here or in children
// TODO
// Criteria 2: declared in ancestor && not modified on any
// non-mutually-exclusive path
// Optimize here: cases where only inserted in this block,
// or no inserts at all
logger.trace("Can optimize!");
replaceInserts(logger, block, blockAliases, init, cand, candKey);
invalid.add(cand); // Don't try to opt in descendants
} else if (vi.insertImmOnce) {
logger.trace("Try to optimize in descendant block!");
// Do nothing: handle in child block
} else {
logger.trace("Optimization not valid!");
// Invalid: can't do optimization anywhere
invalid.add(cand);
}
}
}
for (Statement stmt: block.getStatements()) {
switch (stmt.type()) {
case INSTRUCTION:
// Update which variables are initialized
InitVariables.updateInitVars(logger, stmt, init, false);
break;
case CONDITIONAL:
// Recurse and optimize, plus also update init vars
optRecurseOnCont(logger, f, stmt.conditional(), info, init,
cands, invalid);
break;
}
}
for (Continuation cont: block.getContinuations()) {
optRecurseOnCont(logger, f, cont, info, init, cands, invalid);
}
}
/**
* Try to push down waits from current block into child blocks
* @param logger
* @param fn
* @param block
* @param currContext
* @return
*/
private boolean pushDownWaits(Logger logger, Program prog, Function fn,
Block block, ExecContext currContext) {
SetMultimap<Var, InstOrCont> waitMap = buildWaiterMap(prog, block);
if (logger.isTraceEnabled()) {
logger.trace("waitMap keys: " + waitMap.keySet());
}
if (waitMap.isEmpty()) {
// If waitMap is empty, can't push anything down, so just shortcircuit
return false;
}
boolean changed = false;
HashSet<Continuation> allPushedDown = new HashSet<Continuation>();
ArrayList<Continuation> contCopy =
new ArrayList<Continuation>(block.getContinuations());
for (Continuation c: contCopy) {
if (allPushedDown.contains(c)) {
// Was moved
continue;
}
ExecContext newContext = canPushDownInto(c, currContext);
if (newContext != null) {
for (Block innerBlock: c.getBlocks()) {
StackLite<Continuation> ancestors =
new StackLite<Continuation>();
ancestors.push(c);
PushDownResult pdRes =
pushDownWaitsRec(logger, fn, block, currContext, ancestors,
innerBlock, newContext, waitMap);
changed = changed || pdRes.anyChanges;
/* The list of continuations might be modified as continuations are
* pushed down - track which ones are relocated */
allPushedDown.addAll(pdRes.relocated);
}
}
}
return changed;
}
/**
*
* @param logger
* @param ancestorBlock the block the instructions are moved from
* @param ancestors
* @param currBlock the block they are moved too (a descendant of the prior
* block)
* @param currContext
* @param currBlockIt all changes to instructions in curr block
* are made through this iterator, and it is rewound to the previous position
* before the function exits
* @param waitMap map of variable names to instructions/continuations they block
* on
* @param writtenV
* @return true if change made, list of moved continuations
*/
private Pair<Boolean, Set<Continuation>> relocateDependentInstructions(
Logger logger,
Block ancestorBlock, ExecContext ancestorContext,
StackLite<Continuation> ancestors,
Block currBlock, ExecContext currContext, ListIterator<Statement> currBlockIt,
SetMultimap<Var, InstOrCont> waitMap, Var writtenV) {
boolean changed = false;
// Remove from outer block
Set<InstOrCont> waits = waitMap.get(writtenV);
Set<Instruction> movedI = new HashSet<Instruction>();
Set<Continuation> movedC = new HashSet<Continuation>();
// Rely on later forward Dataflow pass to remove
// unneeded wait vars
/*
* NOTE: instructions/ continuations retain the same relative
* order they were in in the original block, this should help
* optimization pass
*/
for (InstOrCont ic: waits) {
if (logger.isTraceEnabled())
logger.trace("Pushing down: " + ic.toString());
boolean relocated;
switch (ic.type()) {
case CONTINUATION: {
if (logger.isTraceEnabled())
logger.trace("Relocating " + ic.continuation().getType());
relocated = relocateContinuation(ancestors, currBlock,
currContext, movedC, ic.continuation());
break;
}
case INSTRUCTION:
if (logger.isTraceEnabled())
logger.trace("Relocating " + ic.instruction());
relocated = relocateInstruction(ancestors, currContext,
currBlock, currBlockIt, movedI, ic.instruction());
break;
default:
throw new STCRuntimeError("how on earth did we get here...");
}
changed = changed || relocated;
}
// Remove instructions from old block
ancestorBlock.removeContinuations(movedC);
ancestorBlock.removeStatements(movedI);
// Rewind iterator so that next instruction returned
// will be the first one added
ICUtil.rewindIterator(currBlockIt, movedI.size());
// Rebuild wait map to reflect changes
updateWaiterMap(waitMap, movedC, movedI);
return Pair.create(changed, movedC);
}
public static void trace(Logger logger,String message){
if(logger.isTraceEnabled())logger.trace(message);
}
private void piggybackOnContinuations(Logger logger, Function fn,
Block block, RCTracker tracker, RCDir dir, RefCountType rcType,
RefCountCandidates candidates, UseFinder subblockWalker, boolean reverse) {
// Try to piggyback on continuations, starting at bottom up
ListIterator<Continuation> cit = reverse ? block.continuationEndIterator()
: block.continuationIterator();
while ((reverse && cit.hasPrevious()) || (!reverse && cit.hasNext())) {
Continuation cont;
if (reverse) {
cont = cit.previous();
} else {
cont = cit.next();
}
if (RCUtil.isAsyncForeachLoop(cont)) {
AbstractForeachLoop loop = (AbstractForeachLoop) cont;
VarCount piggybacked;
do {
/* Process one at a time so that candidates is correctly updated
* for each call based on previous changes */
piggybacked = loop.tryPiggyBack(candidates, rcType, dir);
if (piggybacked != null) {
if (logger.isTraceEnabled()) {
logger.trace("Piggybacked on foreach: " + piggybacked + " " +
rcType + " " + piggybacked.count);
}
candidates.add(piggybacked.var, -piggybacked.count);
tracker.cancel(tracker.getRefCountVar(piggybacked.var), rcType,
-piggybacked.count);
}
} while (piggybacked != null);
}
// Walk continuation to find usages
subblockWalker.reset();
TreeWalk.walkSyncChildren(logger, fn, cont, subblockWalker);
removeCandidates(subblockWalker.getUsedVars(), tracker, candidates);
}
}
/**
* @param rootBlock
* @return true if the block makes progress of the specified type
*/
public static boolean blockProgress(Block rootBlock, Category type) {
Logger logger = Logging.getSTCLogger();
StackLite<Block> stack = new StackLite<Block>();
stack.push(rootBlock);
while (!stack.isEmpty()) {
Block block = stack.pop();
for (Statement stmt: block.getStatements()) {
if (stmt.type() == StatementType.INSTRUCTION) {
Instruction i = stmt.instruction();
if (type == Category.CHEAP) {
if (!i.isCheap()) {
if (logger.isTraceEnabled()) {
logger.trace("non-cheap instruction found: " + i);
}
return false;
}
} else if (type == Category.CHEAP_WORKER) {
if (!isCheapWorkerInst(i)) {
if (logger.isTraceEnabled()) {
logger.trace("non-cheap-worker instruction found: " + i);
}
return false;
}
} else {
assert(type == Category.NON_PROGRESS);
if (i.isProgressEnabling() || !i.isCheap()) {
if (logger.isTraceEnabled()) {
logger.trace("progress instruction found: " + i);
}
return false;
}
}
}
}
for (Continuation c: block.allComplexStatements()) {
if (!c.isAsync()) {
for (Block inner: c.getBlocks()) {
stack.push(inner);
}
}
}
}
return true;
}
/**
*
* @param logger
* @param fn
* @param block
* @param cv
* @param inst
* @param insts
* if instructions inserted, leaves iterator pointing at previous
* instruction
* @return
*/
private boolean switchToImmediate(Logger logger, Function fn,
ExecContext execCx, Block block, Congruences state,
Instruction inst, ListIterator<Statement> stmts, int stmtIndex) {
if (!finalizedVarEnabled) {
return false;
}
// First see if we can replace some futures with values
MakeImmRequest req = inst.canMakeImmediate(state.getClosed(stmtIndex),
state.getClosedLocs(stmtIndex),
state.retrieveResultAvail(), false);
if (req == null) {
return false;
}
// Create replacement sequence
Block insertContext;
ListIterator<Statement> insertPoint;
boolean waitRequired = req.mode.isDispatched() ||
!req.mode.targetContextMatches(execCx);
// First remove old instruction
stmts.remove();
if (!waitRequired) {
insertContext = block;
insertPoint = stmts;
} else {
WaitStatement wait = new WaitStatement(fn.id() + "-"
+ inst.shortOpName(), WaitVar.NONE, PassedVar.NONE, Var.NONE,
WaitMode.TASK_DISPATCH, false, req.mode, inst.getTaskProps());
insertContext = wait.getBlock();
block.addContinuation(wait);
// Insert at start of block
insertPoint = insertContext.statementIterator();
}
// Now load the values
List<Statement> alt = new ArrayList<Statement>();
List<Fetched<Arg>> inVals = fetchInputsForSwitch(state, req,
insertContext, !waitRequired, alt);
if (logger.isTraceEnabled()) {
logger.trace("Fetched " + inVals + " for " + inst
+ " req.in: " + req.in);
}
// Need filenames for output file values
Map<Var, Var> filenameVals = loadOutputFileNames(state, stmtIndex,
req.out, insertContext, insertPoint);
List<Var> outFetched = OptUtil.createLocalOpOutputVars(insertContext,
insertPoint, req.out, filenameVals);
state.varDeclarations(outFetched);
MakeImmChange change;
change = inst.makeImmediate(new OptVarCreator(block),
Fetched.makeList(req.out, outFetched, true), inVals);
OptUtil.fixupImmChange(fn.id(), block, insertContext, inst, change, alt,
outFetched, req.out);
if (logger.isTraceEnabled()) {
logger.trace("Replacing instruction <" + inst + "> with sequence "
+ alt.toString());
}
// Add new instructions at insert point
for (Statement newStmt : alt) {
insertPoint.add(newStmt);
}
// Rewind argument iterator to instruction before replaced one
if (stmts == insertPoint) {
ICUtil.rewindIterator(stmts, alt.size());
}
return true;
}