diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h index 4f89f8b85861e..5569392cf0b41 100644 --- a/mlir/include/mlir/IR/Operation.h +++ b/mlir/include/mlir/IR/Operation.h @@ -1106,6 +1106,8 @@ inline raw_ostream &operator<<(raw_ostream &os, const Operation &op) { /// useful to act as a "stream modifier" to customize printing an operation /// with a stream using the operator<< overload, e.g.: /// llvm::dbgs() << OpWithFlags(op, OpPrintingFlags().skipRegions()); +/// This always prints the operation with the local scope, to avoid introducing +/// spurious newlines in the stream. class OpWithFlags { public: OpWithFlags(Operation *op, OpPrintingFlags flags = {}) @@ -1116,11 +1118,11 @@ class OpWithFlags { private: Operation *op; OpPrintingFlags theFlags; - friend raw_ostream &operator<<(raw_ostream &os, const OpWithFlags &op); + friend raw_ostream &operator<<(raw_ostream &os, OpWithFlags op); }; -inline raw_ostream &operator<<(raw_ostream &os, - const OpWithFlags &opWithFlags) { +inline raw_ostream &operator<<(raw_ostream &os, OpWithFlags opWithFlags) { + opWithFlags.flags().useLocalScope(); opWithFlags.op->print(os, opWithFlags.flags()); return os; } diff --git a/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp index 4addff9610e88..9424eff3e6b6f 100644 --- a/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp +++ b/mlir/lib/Analysis/DataFlow/DeadCodeAnalysis.cpp @@ -79,9 +79,17 @@ void Executable::onUpdate(DataFlowSolver *solver) const { void PredecessorState::print(raw_ostream &os) const { if (allPredecessorsKnown()) os << "(all) "; - os << "predecessors:\n"; - for (Operation *op : getKnownPredecessors()) - os << " " << *op << "\n"; + os << "predecessors:"; + if (getKnownPredecessors().empty()) + os << " (none)"; + else + os << "\n"; + llvm::interleave( + getKnownPredecessors(), os, + [&](Operation *op) { + os << " " << OpWithFlags(op, OpPrintingFlags().skipRegions()); + }, + "\n"); } ChangeResult PredecessorState::join(Operation *predecessor) { @@ -128,7 +136,7 @@ DeadCodeAnalysis::DeadCodeAnalysis(DataFlowSolver &solver) LogicalResult DeadCodeAnalysis::initialize(Operation *top) { LDBG() << "Initializing DeadCodeAnalysis for top-level op: " - << top->getName(); + << OpWithFlags(top, OpPrintingFlags().skipRegions()); // Mark the top-level blocks as executable. for (Region ®ion : top->getRegions()) { if (region.empty()) @@ -136,7 +144,8 @@ LogicalResult DeadCodeAnalysis::initialize(Operation *top) { auto *state = getOrCreate(getProgramPointBefore(®ion.front())); propagateIfChanged(state, state->setToLive()); - LDBG() << "Marked entry block live for region in op: " << top->getName(); + LDBG() << "Marked entry block live for region in op: " + << OpWithFlags(top, OpPrintingFlags().skipRegions()); } // Mark as overdefined the predecessors of symbol callables with potentially @@ -151,14 +160,16 @@ void DeadCodeAnalysis::initializeSymbolCallables(Operation *top) { << OpWithFlags(top, OpPrintingFlags().skipRegions()); analysisScope = top; auto walkFn = [&](Operation *symTable, bool allUsesVisible) { - LDBG() << "[init] Processing symbol table op: " << symTable->getName(); + LDBG() << "[init] Processing symbol table op: " + << OpWithFlags(symTable, OpPrintingFlags().skipRegions()); Region &symbolTableRegion = symTable->getRegion(0); Block *symbolTableBlock = &symbolTableRegion.front(); bool foundSymbolCallable = false; for (auto callable : symbolTableBlock->getOps()) { LDBG() << "[init] Found CallableOpInterface: " - << callable.getOperation()->getName(); + << OpWithFlags(callable.getOperation(), + OpPrintingFlags().skipRegions()); Region *callableRegion = callable.getCallableRegion(); if (!callableRegion) continue; @@ -173,7 +184,8 @@ void DeadCodeAnalysis::initializeSymbolCallables(Operation *top) { getOrCreate(getProgramPointAfter(callable)); propagateIfChanged(state, state->setHasUnknownPredecessors()); LDBG() << "[init] Marked callable as having unknown predecessors: " - << callable.getOperation()->getName(); + << OpWithFlags(callable.getOperation(), + OpPrintingFlags().skipRegions()); } foundSymbolCallable = true; } @@ -196,7 +208,8 @@ void DeadCodeAnalysis::initializeSymbolCallables(Operation *top) { propagateIfChanged(state, state->setHasUnknownPredecessors()); LDBG() << "[init] Marked nested callable as " "having unknown predecessors: " - << callable.getOperation()->getName(); + << OpWithFlags(callable.getOperation(), + OpPrintingFlags().skipRegions()); }); } @@ -212,7 +225,7 @@ void DeadCodeAnalysis::initializeSymbolCallables(Operation *top) { propagateIfChanged(state, state->setHasUnknownPredecessors()); LDBG() << "[init] Found non-call use for symbol, " "marked as having unknown predecessors: " - << symbol->getName(); + << OpWithFlags(symbol, OpPrintingFlags().skipRegions()); } }; SymbolTable::walkSymbolTables(top, /*allSymUsesVisible=*/!top->getBlock(), @@ -235,7 +248,8 @@ LogicalResult DeadCodeAnalysis::initializeRecursively(Operation *op) { // Initialize the analysis by visiting every op with control-flow semantics. if (op->getNumRegions() || op->getNumSuccessors() || isRegionOrCallableReturn(op) || isa(op)) { - LDBG() << "[init] Visiting op with control-flow semantics: " << *op; + LDBG() << "[init] Visiting op with control-flow semantics: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); // When the liveness of the parent block changes, make sure to // re-invoke the analysis on the op. if (op->getBlock()) @@ -247,7 +261,8 @@ LogicalResult DeadCodeAnalysis::initializeRecursively(Operation *op) { } // Recurse on nested operations. for (Region ®ion : op->getRegions()) { - LDBG() << "[init] Recursing into region of op: " << op->getName(); + LDBG() << "[init] Recursing into region of op: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); for (Operation &nestedOp : region.getOps()) { LDBG() << "[init] Recursing into nested op: " << OpWithFlags(&nestedOp, OpPrintingFlags().skipRegions()); @@ -270,14 +285,16 @@ void DeadCodeAnalysis::markEdgeLive(Block *from, Block *to) { } void DeadCodeAnalysis::markEntryBlocksLive(Operation *op) { - LDBG() << "Marking entry blocks live for op: " << op->getName(); + LDBG() << "Marking entry blocks live for op: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); for (Region ®ion : op->getRegions()) { if (region.empty()) continue; auto *state = getOrCreate(getProgramPointBefore(®ion.front())); propagateIfChanged(state, state->setToLive()); - LDBG() << "Marked entry block live for region in op: " << op->getName(); + LDBG() << "Marked entry block live for region in op: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); } } @@ -286,19 +303,22 @@ LogicalResult DeadCodeAnalysis::visit(ProgramPoint *point) { if (point->isBlockStart()) return success(); Operation *op = point->getPrevOp(); - LDBG() << "Visiting operation: " << *op; + LDBG() << "Visiting operation: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); // If the parent block is not executable, there is nothing to do. if (op->getBlock() != nullptr && !getOrCreate(getProgramPointBefore(op->getBlock())) ->isLive()) { - LDBG() << "Parent block not live, skipping op: " << *op; + LDBG() << "Parent block not live, skipping op: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); return success(); } // We have a live call op. Add this as a live predecessor of the callee. if (auto call = dyn_cast(op)) { - LDBG() << "Visiting call operation: " << *op; + LDBG() << "Visiting call operation: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); visitCallOperation(call); } @@ -306,12 +326,14 @@ LogicalResult DeadCodeAnalysis::visit(ProgramPoint *point) { if (op->getNumRegions()) { // Check if we can reason about the region control-flow. if (auto branch = dyn_cast(op)) { - LDBG() << "Visiting region branch operation: " << *op; + LDBG() << "Visiting region branch operation: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); visitRegionBranchOperation(branch); // Check if this is a callable operation. } else if (auto callable = dyn_cast(op)) { - LDBG() << "Visiting callable operation: " << *op; + LDBG() << "Visiting callable operation: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); const auto *callsites = getOrCreateFor( getProgramPointAfter(op), getProgramPointAfter(callable)); @@ -323,19 +345,22 @@ LogicalResult DeadCodeAnalysis::visit(ProgramPoint *point) { // Otherwise, conservatively mark all entry blocks as executable. } else { - LDBG() << "Marking all entry blocks live for op: " << *op; + LDBG() << "Marking all entry blocks live for op: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); markEntryBlocksLive(op); } } if (isRegionOrCallableReturn(op)) { if (auto branch = dyn_cast(op->getParentOp())) { - LDBG() << "Visiting region terminator: " << *op; + LDBG() << "Visiting region terminator: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); // Visit the exiting terminator of a region. visitRegionTerminator(op, branch); } else if (auto callable = dyn_cast(op->getParentOp())) { - LDBG() << "Visiting callable terminator: " << *op; + LDBG() << "Visiting callable terminator: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); // Visit the exiting terminator of a callable. visitCallableTerminator(op, callable); } @@ -344,12 +369,14 @@ LogicalResult DeadCodeAnalysis::visit(ProgramPoint *point) { if (op->getNumSuccessors()) { // Check if we can reason about the control-flow. if (auto branch = dyn_cast(op)) { - LDBG() << "Visiting branch operation: " << *op; + LDBG() << "Visiting branch operation: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); visitBranchOperation(branch); // Otherwise, conservatively mark all successors as exectuable. } else { - LDBG() << "Marking all successors live for op: " << *op; + LDBG() << "Marking all successors live for op: " + << OpWithFlags(op, OpPrintingFlags().skipRegions()); for (Block *successor : op->getSuccessors()) markEdgeLive(op->getBlock(), successor); } @@ -359,7 +386,8 @@ LogicalResult DeadCodeAnalysis::visit(ProgramPoint *point) { } void DeadCodeAnalysis::visitCallOperation(CallOpInterface call) { - LDBG() << "visitCallOperation: " << call.getOperation()->getName(); + LDBG() << "visitCallOperation: " + << OpWithFlags(call.getOperation(), OpPrintingFlags().skipRegions()); Operation *callableOp = call.resolveCallableInTable(&symbolTable); // A call to a externally-defined callable has unknown predecessors. @@ -442,7 +470,8 @@ void DeadCodeAnalysis::visitBranchOperation(BranchOpInterface branch) { void DeadCodeAnalysis::visitRegionBranchOperation( RegionBranchOpInterface branch) { - LDBG() << "visitRegionBranchOperation: " << branch.getOperation()->getName(); + LDBG() << "visitRegionBranchOperation: " + << OpWithFlags(branch.getOperation(), OpPrintingFlags().skipRegions()); // Try to deduce which regions are executable. std::optional> operands = getOperandValues(branch); if (!operands) @@ -519,14 +548,14 @@ void DeadCodeAnalysis::visitCallableTerminator(Operation *op, if (canResolve) { propagateIfChanged(predecessors, predecessors->join(op)); LDBG() << "Added callable terminator as predecessor for callsite: " - << predecessor->getName(); + << OpWithFlags(predecessor, OpPrintingFlags().skipRegions()); } else { // If the terminator is not a return-like, then conservatively assume we // can't resolve the predecessor. propagateIfChanged(predecessors, predecessors->setHasUnknownPredecessors()); LDBG() << "Could not resolve callable terminator for callsite: " - << predecessor->getName(); + << OpWithFlags(predecessor, OpPrintingFlags().skipRegions()); } } } diff --git a/mlir/lib/Analysis/DataFlowFramework.cpp b/mlir/lib/Analysis/DataFlowFramework.cpp index 76bf94aed9e02..7e1b4052027d3 100644 --- a/mlir/lib/Analysis/DataFlowFramework.cpp +++ b/mlir/lib/Analysis/DataFlowFramework.cpp @@ -62,11 +62,12 @@ void ProgramPoint::print(raw_ostream &os) const { return; } if (!isBlockStart()) { - os << ":"; - return getPrevOp()->print(os, OpPrintingFlags().skipRegions()); + os << ":" + << OpWithFlags(getPrevOp(), OpPrintingFlags().skipRegions()); + return; } - os << ":"; - return getNextOp()->print(os, OpPrintingFlags().skipRegions()); + os << ":" + << OpWithFlags(getNextOp(), OpPrintingFlags().skipRegions()); } //===----------------------------------------------------------------------===//