Skip to content

Conversation

@maerhart
Copy link
Member

Depends on #66626
Only review top commit.

@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir:linalg mlir mlir:bufferization Bufferization infrastructure mlir:arith labels Sep 27, 2023
…ction boundary ABI Inserting clones requires a lot of assumptions to hold on the input IR, e.g., all writes to a buffer need to dominate all reads. This is not guaranteed by one-shot bufferization and isn't easy to verify, thus it could quickly lead to incorrect results that are hard to debug. This commit changes the mechanism of how an ownership indicator is materialized when there is not already a unique ownership present. Additionally, we don't create copies of returned memrefs anymore when we don't have ownership. Instead, we insert assert operations to make sure we have ownership at runtime, or otherwise report to the user that correctness could not be guaranteed.
…loc operations, add option to specify the kind of alloc operations to consider
/// ownership will be set to 'false', i.e., it will be leaked. This is useful
/// to support deallocation of multiple different kinds of allocation ops.
DetectionFn isRelevantAllocOp = [](Operation *op) {
return isa<memref::MemRefDialect, bufferization::BufferizationDialect>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the bufferization dialect in here? Can we just check for memref.alloc/memref.alloca in here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BufferizationDialect is here because of bufferization.clone which has an allocation side-effect as well.

/// changed with this option.
bool verifyFunctionBoundaryABI = true;

/// Given an allocation side-effect on the passed operation, determine whether
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given an operation with an allocation side effect

op->getDialect());
};

/// Given a free side-effect on the passed operation, determine whether this
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given an operation with a free side effect

PassOptions::Option<bool> removeExistingDeallocations{
*this, "remove-existing-deallocations",
llvm::cl::desc("Removes all pre-existing memref.dealloc operations and "
"insert all deallocations according to the buffer "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think just Removes pre-existing memref.dealloc operations should be enough.

"be changed with this option.">,
Option<"removeExistingDeallocations", "remove-existing-deallocations",
"bool", /*default=*/"false",
"Remove already existing MemRef deallocation operations and let the "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

}

// Alloc operations from other dialects are expected to have matching
// deallocation operations inserted by another pass.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inserted by a separate run of this pass

auto allocEffect = op.getEffectOnValue<MemoryEffects::Allocate>(res);
if (allocEffect.has_value()) {
// Assuming that an alloc effect is interpreted as MUST and not MAY.
state.resetOwnerships(res, block);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this doing?


WalkResult result = getOperation()->walk([&](FunctionOpInterface funcOp) {
// Deallocate the `memref.alloc` operations.
bufferization::DeallocationOptions options;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment that by default the deallocation options are configured to look for memref.alloc/memref.dealloc only.

}
return ValueRange{};
}
return failure();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be llvm_unreachable("expected gpu.dealloc op")? Then you could also make the gpuDealloc a cast<DeallocOp> and you won't need the "if" check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mlir:arith mlir:bufferization Bufferization infrastructure mlir:core MLIR Core Infrastructure mlir:linalg mlir

3 participants