Skip to content

Commit

Permalink
Update external bufferization interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
hanchenye committed Jan 7, 2024
1 parent b11f5ac commit c9d7312
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 26 deletions.
14 changes: 7 additions & 7 deletions include/scalehls/Dialect/HLS/IR/HLSOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def AllocTensorOp : HLSOp<"fdf.alloc_tensor", [NoMemoryEffect]> {
];
}

def TensorToStreamOp : HLSOp<"ubuf.tensor_to_stream",[
def TensorToStreamOp : HLSOp<"fdf.tensor_to_stream",[
AttrSizedOperandSegments, NoMemoryEffect]> {
let summary = "Convert a tensor to a stream channel";

Expand All @@ -135,7 +135,7 @@ def TensorToStreamOp : HLSOp<"ubuf.tensor_to_stream",[
}];
}

def StreamToTensorOp : HLSOp<"ubuf.stream_to_tensor", [
def StreamToTensorOp : HLSOp<"fdf.stream_to_tensor", [
AttrSizedOperandSegments, NoMemoryEffect]> {
let summary = "Convert a stream channel to a tensor";

Expand Down Expand Up @@ -269,7 +269,7 @@ def NodeOp : HLSOp<"sdf.node", [
}];
}

def BufferOp : HLSOp<"ubuf.buffer", [
def BufferOp : HLSOp<"sdf.buffer", [
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
DeclareOpInterfaceMethods<BufferLikeInterface>]> {
let summary = "Represent a dataflow buffer";
Expand All @@ -287,7 +287,7 @@ def BufferOp : HLSOp<"ubuf.buffer", [
];
}

def ConstBufferOp : HLSOp<"ubuf.const_buffer", [
def ConstBufferOp : HLSOp<"sdf.const_buffer", [
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
DeclareOpInterfaceMethods<BufferLikeInterface>]> {
let summary = "Represent a constant dataflow buffer";
Expand All @@ -299,7 +299,7 @@ def ConstBufferOp : HLSOp<"ubuf.const_buffer", [
let hasVerifier = 1;
}

def StreamOp : HLSOp<"ubuf.stream", [
def StreamOp : HLSOp<"sdf.stream", [
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
let summary = "Declare a stream channel";

Expand All @@ -314,7 +314,7 @@ def StreamOp : HLSOp<"ubuf.stream", [
];
}

def StreamReadOp : HLSOp<"ubuf.stream_read", []> {
def StreamReadOp : HLSOp<"sdf.stream_read", []> {
let summary = "Read a stream channel";
let description = [{
Read/pop a value from a stream channel. The absence of the result indicates
Expand All @@ -330,7 +330,7 @@ def StreamReadOp : HLSOp<"ubuf.stream_read", []> {
let hasVerifier = 1;
}

def StreamWriteOp : HLSOp<"ubuf.stream_write", []> {
def StreamWriteOp : HLSOp<"sdf.stream_write", []> {
let summary = "Write a stream channel";
let description = [{
Write/push a value to a stream channel. Each stream channel can only be
Expand Down
39 changes: 22 additions & 17 deletions lib/Dialect/HLS/Transforms/BufferizableOpInterfaceImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ template <typename OpType>
struct DispatchOrTaskOpInterface
: public BufferizableOpInterface::ExternalModel<
DispatchOrTaskOpInterface<OpType>, OpType> {
/// Dispatch/task do not have tensor OpOperands. Thus, no OpOperand will be
/// bufferized to memory read/write or be aliased to any returned values.
AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return {};
}

// Dispatch/task do not have tensor OpOperands. The yielded value can be any
// SSA value that is in scope. To allow for use-def chain traversal in the
// analysis, the yielded value is aliasing with the result.
AliasingOpOperandList
getAliasingOpOperands(Operation *op, Value value,
const AnalysisState &state) const {
// Dispatch/task do not have tensor OpOperands. The yielded value can be any
// SSA value that is in scope. To allow for use-def chain traversal in the
// analysis, the yielded value is aliasing with the result.
size_t resultNum = std::distance(op->getOpResults().begin(),
llvm::find(op->getOpResults(), value));
size_t resultNum = std::distance(op->getResults().begin(),
llvm::find(op->getResults(), value));
OpOperand *operand =
&cast<OpType>(op).getYieldOp()->getOpOperand(resultNum);
return {{operand, BufferRelation::Equivalent}};
Expand All @@ -35,11 +42,10 @@ struct DispatchOrTaskOpInterface
LogicalResult bufferize(Operation *op, RewriterBase &rewriter,
const BufferizationOptions &options) const {
OpBuilder::InsertionGuard g(rewriter);
auto task = cast<OpType>(op);

// Compute bufferized result types.
SmallVector<Type> newTypes;
for (Value result : task.getResults()) {
for (Value result : op->getResults()) {
if (!result.getType().isa<TensorType>()) {
newTypes.push_back(result.getType());
continue;
Expand All @@ -51,13 +57,13 @@ struct DispatchOrTaskOpInterface
}

// Create new dispatch/task op.
rewriter.setInsertionPoint(task);
auto newTask = rewriter.create<OpType>(task.getLoc(), newTypes);
rewriter.inlineRegionBefore(task.getBody(), newTask.getBody(),
newTask.getBody().end());
rewriter.setInsertionPoint(op);
auto newOp = rewriter.create<OpType>(op->getLoc(), newTypes);
rewriter.inlineRegionBefore(cast<OpType>(op).getBody(), newOp.getBody(),
newOp.getBody().end());

// Replace dispatch/task op results.
replaceOpWithBufferizedValues(rewriter, op, newTask->getResults());
replaceOpWithBufferizedValues(rewriter, op, newOp->getResults());
return success();
}

Expand Down Expand Up @@ -88,14 +94,13 @@ struct YieldOpInterface
const AnalysisState &state) const {
return true;
}

bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return false;
}

AliasingValueList getAliasingOpResults(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
if (isa<DispatchOp, TaskOp>(op->getParentOp()))
return {{op->getParentOp()->getResult(opOperand.getOperandNumber()),
BufferRelation::Equivalent}};
Expand Down Expand Up @@ -174,8 +179,8 @@ struct AllocTensorOpInterface

bool bufferizesToAllocation(Operation *op, Value value) const { return true; }

AliasingValueList getAliasingOpResults(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
// This is a new allocation. It does not alias with any other buffer.
return {};
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Transforms/Pipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ void scalehls::addComprehensiveBufferizePasses(OpPassManager &pm) {
// can be deleted by canonicalizer. We have to run it again because the
// memrefs are unified in CSE pass, so we can truely remove redundant memcpy.
pm.addPass(mlir::createCanonicalizerPass());
pm.addNestedPass<func::FuncOp>(hls::createEliminateBufferYieldPass());
pm.addPass(mlir::createCanonicalizerPass());
// pm.addNestedPass<func::FuncOp>(hls::createEliminateBufferYieldPass());
// pm.addPass(mlir::createCanonicalizerPass());
}

void scalehls::addLowerDataflowPasses(OpPassManager &pm) {
Expand Down

0 comments on commit c9d7312

Please sign in to comment.