bool insideMutuallyExclusiveBranches(Operation *a, Operation *b);
/// An owning vector of values, handy to return from functions.
-using ValueVector = std::vector<Value>;
-using LoopVector = std::vector<scf::ForOp>;
+using ValueVector = SmallVector<Value>;
+using LoopVector = SmallVector<scf::ForOp>;
struct LoopNest {
- ResultRange getResults() { return loops.front().getResults(); }
LoopVector loops;
+ ValueVector results;
};
/// Creates a perfect nest of "for" loops, i.e. all loops but the innermost
if (failed(tilePadOp(rewriter, op, newPadOp, loopNest, options)))
return failure();
// Replace all uses of the original tensor::PadOp.
- rewriter.replaceOp(op, loopNest.getResults()[0]);
+ rewriter.replaceOp(op, loopNest.results.front());
return success();
}
assert(results.size() == iterArgs.size() &&
"loop nest body must return as many values as loop has iteration "
"arguments");
- return LoopNest();
+ return LoopNest{{}, std::move(results)};
}
// First, create the loop structure iteratively using the body-builder
builder.create<scf::YieldOp>(loc, results);
// Return the loops.
- LoopNest res;
- res.loops.assign(loops.begin(), loops.end());
- return res;
+ ValueVector nestResults;
+ llvm::copy(loops.front().getResults(), std::back_inserter(nestResults));
+ return LoopNest{std::move(loops), std::move(nestResults)};
}
LoopNest mlir::scf::buildLoopNest(
SmallVector<Value> lbs(numTiledDims, zero);
SmallVector<Value> steps(numTiledDims, one);
- // Below, we pass out the result of the loop body builder lambda via the
- // `insertResult` variable. In certain cases, no loops will be created, but
- // the body builder will still execute. In this case, the results will not
- // be passed to the LoopNest object.
- // TODO: remove this workaround if `scf::buildLoopNest` behavior is updated.
- Value insertResult = nullptr;
scf::LoopNest nest = scf::buildLoopNest(
rewriter, loc, lbs, helper.getIterationSpaceSizes(), steps, dest,
[&](OpBuilder &nestedBuilder, Location loc, ValueRange outputIvs,
helper.emitLoopNestBody(nestedBuilder, loc, outputIvs);
// Insert the slice into the destination.
- insertResult = nestedBuilder.create<tensor::InsertSliceOp>(
- loc, tile, iterArgs[0], insertParams);
- return {insertResult};
+ return {nestedBuilder.create<tensor::InsertSliceOp>(
+ loc, tile, iterArgs[0], insertParams)};
});
-
- if (!nest.loops.empty())
- rewriter.replaceOp(op, nest.getResults());
- else
- rewriter.replaceOp(op, insertResult);
+ rewriter.replaceOp(op, nest.results);
return success();
}