49 for (mlir::Region ®ion : top->getRegions()) {
50 for (mlir::Block &block : region) {
51 (void)solver.getOrCreateState<mlir::dataflow::Executable>(&block)->setToLive();
52 for (mlir::Operation &oper : block) {
66 for (Region ®ion : top->getRegions()) {
67 for (Block &block : region) {
69 for (Operation &op : block) {
80 if (
auto *op = llvm::dyn_cast_if_present<Operation *>(point)) {
82 }
else if (
auto *block = llvm::dyn_cast_if_present<Block *>(point)) {
92void AbstractDenseForwardDataFlowAnalysis::visitCallOperation(
98 if (!getSolverConfig().isInterprocedural() ||
99 (mlir::succeeded(callable) && !callable->get().getCallableRegion())) {
105 SmallVector<Operation *> predecessors;
106 auto fnOp = callable.value().get();
107 fnOp.walk([&predecessors](
ReturnOp ret)
mutable { predecessors.push_back(ret); });
111 if (predecessors.empty()) {
115 for (Operation *predecessor : predecessors) {
133 call, CallControlFlowAction::ExitCallee, *latticeAtCalleeReturn, latticeAfterCall
140 if (!getOrCreateFor<Executable>(op, op->getBlock())->isLive()) {
149 if (Operation *prev = op->getPrevNode()) {
157 if (
auto branch = dyn_cast<RegionBranchOpInterface>(op)) {
163 if (
auto call = dyn_cast<CallOpInterface>(op)) {
164 return visitCallOperation(call, *before, after);
173void AbstractDenseForwardDataFlowAnalysis::visitBlock(Block *block) {
175 if (!getOrCreateFor<Executable>(block, block)->isLive()) {
184 if (block->isEntryBlock()) {
186 auto callable = dyn_cast<CallableOpInterface>(block->getParentOp());
187 if (callable && callable.getCallableRegion() == block->getParent()) {
188 if (!getSolverConfig().isInterprocedural()) {
193 ensure(mlir::succeeded(moduleOpRes),
"could not get root module from callable");
195 SmallVector<Operation *> callsites;
196 moduleOpRes->walk([
this, &callable, &callsites](CallOp call)
mutable {
198 if (mlir::succeeded(calledFnRes) &&
199 calledFnRes->get().getCallableRegion() == callable.getCallableRegion()) {
200 callsites.push_back(call);
204 for (Operation *callsite : callsites) {
207 if (Operation *prev = callsite->getPrevNode()) {
214 llvm::cast<CallOpInterface>(callsite), CallControlFlowAction::EnterCallee, *before,
222 if (
auto branch = dyn_cast<RegionBranchOpInterface>(block->getParentOp())) {
231 for (Block::pred_iterator it = block->pred_begin(), e = block->pred_end(); it != e; ++it) {
233 Block *predecessor = *it;
234 if (!getOrCreateFor<Executable>(block, getProgramPoint<CFGEdge>(predecessor, block))
248 const auto *predecessors = getOrCreateFor<PredecessorState>(point, point);
249 assert(predecessors->allPredecessorsKnown() &&
"unexpected unresolved region successors");
251 for (Operation *op : predecessors->getKnownPredecessors()) {
255 if (Operation *prev = op->getPrevNode()) {
279 std::optional<unsigned> regionFrom =
280 op == branch ? std::optional<unsigned>() : op->getBlock()->getParent()->getRegionNumber();
281 if (
auto *toBlock = point.dyn_cast<Block *>()) {
282 unsigned regionTo = toBlock->getParent()->getRegionNumber();
285 assert(point.get<Operation *>() == branch &&
"expected to be visiting the branch itself");
288 if (op->getParentOp() == branch || op == branch) {
290 branch, regionFrom, std::nullopt, *before, after
293 join(after, *before);
302 addDependency(state, dependent);
virtual void visitCallControlFlowTransfer(mlir::CallOpInterface call, CallControlFlowAction action, const AbstractDenseLattice &before, AbstractDenseLattice *after)
Propagate the dense lattice forward along the call control flow edge, which can be either entering or...
virtual void visitRegionBranchControlFlowTransfer(mlir::RegionBranchOpInterface branch, std::optional< unsigned > regionFrom, std::optional< unsigned > regionTo, const AbstractDenseLattice &before, AbstractDenseLattice *after)
Propagate the dense lattice forward along the control flow edge from regionFrom to regionTo regions o...
mlir::FailureOr< SymbolLookupResult< T > > resolveCallable(mlir::SymbolTableCollection &symbolTable, mlir::CallOpInterface call)
Based on mlir::CallOpInterface::resolveCallable, but using LLZK lookup helpers.