5757#include " llvm/ADT/DenseSet.h"
5858#include " llvm/ADT/SetVector.h"
5959
60+ // Run mlir-opt with `-debug-only="one-shot-analysis"` for detailed debug
61+ // output.
62+ #define DEBUG_TYPE " one-shot-analysis"
63+
6064using namespace mlir ;
6165using namespace mlir ::bufferization;
6266
@@ -553,6 +557,7 @@ static bool hasReadAfterWriteInterference(
553557
554558 // Check if op dominance can be used to rule out read-after-write conflicts.
555559 bool useDominance = canUseOpDominance (usesRead, usesWrite, state);
560+ LLVM_DEBUG (llvm::dbgs () << " \n - useDominance = " << useDominance << " \n " );
556561
557562 for (OpOperand *uRead : usesRead) {
558563 Operation *readingOp = uRead->getOwner ();
@@ -572,6 +577,14 @@ static bool hasReadAfterWriteInterference(
572577 // Look for conflicting memory writes. Potential conflicts are writes to an
573578 // alias that have been decided to bufferize inplace.
574579 for (OpOperand *uConflictingWrite : usesWrite) {
580+ LLVM_DEBUG (llvm::dbgs () << " \n - check conflict:\n " );
581+ LLVM_DEBUG (llvm::dbgs ()
582+ << " uRead = operand " << uRead->getOperandNumber () << " of "
583+ << *uRead->getOwner () << " \n " );
584+ LLVM_DEBUG (llvm::dbgs () << " unConflictingWrite = operand "
585+ << uConflictingWrite->getOperandNumber () << " of "
586+ << *uConflictingWrite->getOwner () << " \n " );
587+
575588 // Throughout this loop, check for multiple requirements that have to be
576589 // met for uConflictingWrite to be an actual conflict.
577590 Operation *conflictingWritingOp = uConflictingWrite->getOwner ();
@@ -585,8 +598,11 @@ static bool hasReadAfterWriteInterference(
585598 // Note: If ops are executed multiple times (e.g., because they are
586599 // inside a loop), there may be no meaningful `happensBefore`
587600 // relationship.
588- if (happensBefore (readingOp, conflictingWritingOp, domInfo))
601+ if (happensBefore (readingOp, conflictingWritingOp, domInfo)) {
602+ LLVM_DEBUG (llvm::dbgs ()
603+ << " no conflict: read happens before write\n " );
589604 continue ;
605+ }
590606
591607 // No conflict if the reading use equals the use of the conflicting
592608 // write. A use cannot conflict with itself.
@@ -595,61 +611,93 @@ static bool hasReadAfterWriteInterference(
595611 // use.
596612 // Note: If the op is executed multiple times (e.g., because it is
597613 // inside a loop), it may be conflicting with itself.
598- if (uConflictingWrite == uRead)
614+ if (uConflictingWrite == uRead) {
615+ LLVM_DEBUG (llvm::dbgs ()
616+ << " no conflict: read and write are same use\n " );
599617 continue ;
618+ }
600619
601620 // Ops are not conflicting if they are in mutually exclusive regions.
602621 //
603622 // Note: If ops are executed multiple times (e.g., because they are
604623 // inside a loop), mutually exclusive regions may be executed
605624 // multiple times.
606- if (insideMutuallyExclusiveRegions (readingOp, conflictingWritingOp))
625+ if (insideMutuallyExclusiveRegions (readingOp, conflictingWritingOp)) {
626+ LLVM_DEBUG (llvm::dbgs () << " no conflict: read and write are in "
627+ " mutually exclusive regions\n " );
607628 continue ;
629+ }
608630 }
609631
610632 // No conflict if the op interface says so.
611- if (auto bufferizableOp = options.dynCastBufferizableOp (readingOp))
612- if (bufferizableOp.isNotConflicting (uRead, uConflictingWrite, state))
633+ if (auto bufferizableOp = options.dynCastBufferizableOp (readingOp)) {
634+ if (bufferizableOp.isNotConflicting (uRead, uConflictingWrite, state)) {
635+ LLVM_DEBUG (llvm::dbgs ()
636+ << " no conflict: op interace of reading op says 'no'\n " );
613637 continue ;
638+ }
639+ }
614640
615- if (conflictingWritingOp != readingOp)
641+ if (conflictingWritingOp != readingOp) {
616642 if (auto bufferizableOp =
617- options.dynCastBufferizableOp (conflictingWritingOp))
618- if (bufferizableOp.isNotConflicting (uRead, uConflictingWrite, state))
643+ options.dynCastBufferizableOp (conflictingWritingOp)) {
644+ if (bufferizableOp.isNotConflicting (uRead, uConflictingWrite,
645+ state)) {
646+ LLVM_DEBUG (
647+ llvm::dbgs ()
648+ << " no conflict: op interace of writing op says 'no'\n " );
619649 continue ;
650+ }
651+ }
652+ }
620653
621654 // Check all possible last writes.
622655 for (Value lastWrite : lastWrites) {
656+ LLVM_DEBUG (llvm::dbgs () << " * lastWrite = " << lastWrite << " \n " );
657+
623658 // No conflict if the conflicting write happens before the last
624659 // write.
625660 if (Operation *writingOp = lastWrite.getDefiningOp ()) {
626- if (happensBefore (conflictingWritingOp, writingOp, domInfo))
661+ if (happensBefore (conflictingWritingOp, writingOp, domInfo)) {
627662 // conflictingWritingOp happens before writingOp. No conflict.
663+ LLVM_DEBUG (llvm::dbgs ()
664+ << " no conflict: write happens before last write\n " );
628665 continue ;
666+ }
629667 // No conflict if conflictingWritingOp is contained in writingOp.
630- if (writingOp->isProperAncestor (conflictingWritingOp))
668+ if (writingOp->isProperAncestor (conflictingWritingOp)) {
669+ LLVM_DEBUG (
670+ llvm::dbgs ()
671+ << " no conflict: write is contained in last write\n " );
631672 continue ;
673+ }
632674 } else {
633675 auto bbArg = lastWrite.cast <BlockArgument>();
634676 Block *block = bbArg.getOwner ();
635- if (!block->findAncestorOpInBlock (*conflictingWritingOp))
677+ if (!block->findAncestorOpInBlock (*conflictingWritingOp)) {
678+ LLVM_DEBUG (llvm::dbgs () << " no conflict: last write is bbArg "
679+ " and write happens outside of block\n " );
636680 // conflictingWritingOp happens outside of the block. No
637681 // conflict.
638682 continue ;
683+ }
639684 }
640685
641686 // No conflict if the conflicting write and the last write are the same
642687 // use.
643688 SmallVector<OpResult> aliasingOpResult =
644689 state.getAliasingOpResult (*uConflictingWrite);
645- if (aliasingOpResult.size () == 1 && aliasingOpResult[0 ] == lastWrite)
690+ if (aliasingOpResult.size () == 1 && aliasingOpResult[0 ] == lastWrite) {
691+ LLVM_DEBUG (llvm::dbgs ()
692+ << " no conflict: last write and write are same\n " );
646693 continue ;
694+ }
647695
648696 // All requirements are met. Conflict found!
649697
650698 if (options.printConflicts )
651699 annotateConflict (uRead, uConflictingWrite, lastWrite);
652-
700+ LLVM_DEBUG ( llvm::dbgs () << " => RaW CONFLICT FOUND \n " );
653701 return true ;
654702 }
655703 }
@@ -803,10 +851,13 @@ static bool wouldCreateWriteToNonWritableBuffer(
803851 // Assuming that `operand` bufferizes in-place: For each write (to each
804852 // alias), check if there is a non-writable tensor in the reverse SSA use-def
805853 // chain.
806- for (OpOperand *uWrite : usesWrite)
854+ for (OpOperand *uWrite : usesWrite) {
807855 if (hasPrecedingAliasingNonWritableTensor (uWrite->get (), &operand,
808- aliasInfo, state))
856+ aliasInfo, state)) {
857+ LLVM_DEBUG (llvm::dbgs () << " => NOT WRITABLE\n " );
809858 return true ;
859+ }
860+ }
810861
811862 return false ;
812863}
@@ -819,6 +870,11 @@ static bool wouldCreateWriteToNonWritableBuffer(
819870static LogicalResult bufferizableInPlaceAnalysisImpl (
820871 OpOperand &operand, BufferizationAliasInfo &aliasInfo,
821872 OneShotAnalysisState &state, const DominanceInfo &domInfo) {
873+ LLVM_DEBUG (
874+ llvm::dbgs () << " //===-------------------------------------------===//\n "
875+ << " Analyzing operand #" << operand.getOperandNumber ()
876+ << " of " << *operand.getOwner () << " \n " );
877+
822878 bool foundInterference =
823879 wouldCreateWriteToNonWritableBuffer (operand, aliasInfo, state) ||
824880 wouldCreateReadAfterWriteInterference (operand, domInfo, state, aliasInfo);
@@ -828,6 +884,8 @@ static LogicalResult bufferizableInPlaceAnalysisImpl(
828884 else
829885 aliasInfo.bufferizeInPlace (operand, state);
830886
887+ LLVM_DEBUG (llvm::dbgs ()
888+ << " //===-------------------------------------------===//\n " );
831889 return success ();
832890}
833891
0 commit comments