-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bit optim #1
Bit optim #1
Changes from 63 commits
b560c22
f904ad8
1249931
4c4a944
fb92e71
4b966a2
954f9d0
92e4321
f5324eb
dad2289
d320a05
39872b4
9f83eb9
74bc628
869bac0
03416b0
408e22c
bfbb468
86e9260
c883258
eb22554
2cb7920
25a7e6b
8d26980
746245a
45d00a6
22afac9
4e9bec7
14bda82
8ccbd06
46df002
b7d4d06
bd9537b
98ce134
4ebcb4a
41fd3b1
4055f4f
7e7fa6e
ec2aab8
fa44c96
bed3bfa
07adc11
b1ea8cf
726e723
02c81cd
602caed
ff97ca9
01f3c21
ea509e2
0a0b8dd
1c3ca05
93b8db4
575ccb0
bbf5c3e
b21198d
2922aba
207339d
cfc19e8
9eb4abe
36aec81
910b692
6f5e707
48d0817
dfa6481
ec01912
45d2911
39c4f08
3d139f7
121d633
091e76d
1660931
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,4 +34,4 @@ | |
# Build-related directories | ||
build/ | ||
bin/ | ||
.cache/ | ||
.cache/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//===- InitCstWidth.h - Reduce the constant bits width ----------*- C++ -*-===// | ||
// | ||
// This file declares the --init-cstwidth pass. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef DYNAMATIC_TRANSFORMS_INITCSTWIDTH_H | ||
#define DYNAMATIC_TRANSFORMS_INITCSTWIDTH_H | ||
|
||
#include "dynamatic/Transforms/UtilsBitsUpdate.h" | ||
|
||
namespace dynamatic { | ||
|
||
std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>> createInitCstWidthPass(); | ||
|
||
} // namespace dynamatic | ||
|
||
#endif // DYNAMATIC_TRANSFORMS_INITCSTWIDTH_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//===- InitIndexType.h - Transform IndexType to IntegerType -----*- C++ -*-===// | ||
// | ||
// This file declares the --init-indextype pass. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef DYNAMATIC_TRANSFORMS_INITINDTYPE_H | ||
#define DYNAMATIC_TRANSFORMS_INITINDTYPE_H | ||
|
||
#include "dynamatic/Transforms/UtilsBitsUpdate.h" | ||
|
||
namespace dynamatic { | ||
|
||
std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>> createInitIndTypePass(); | ||
|
||
} // namespace dynamatic | ||
|
||
#endif // DYNAMATIC_TRANSFORMS_INITINDTYPE_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//===- BitsOptimize.h - Optimize bits widths --------------------*- C++ -*-===// | ||
// | ||
// This file declares the --optimize-bits pass. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef DYNAMATIC_TRANSFORMS_OPTIMIZEBITS_H | ||
#define DYNAMATIC_TRANSFORMS_OPTIMIZEBITS_H | ||
|
||
#include "dynamatic/Transforms/UtilsBitsUpdate.h" | ||
|
||
namespace dynamatic { | ||
|
||
std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>> createOptimizeBitsPass(); | ||
|
||
} // namespace dynamatic | ||
|
||
#endif // DYNAMATIC_TRANSFORMS_OPTIMIZEBITS_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
//===- UtilsBitsUpdate.h - Utils support bits optimization ------*- C++ -*-===// | ||
// | ||
// This file declares supports for --optimize-bits pass. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef DYNAMATIC_TRANSFORMS_UTILSBITSUPDATE_H | ||
#define DYNAMATIC_TRANSFORMS_UTILSBITSUPDATE_H | ||
|
||
#include "circt/Dialect/Handshake/HandshakeOps.h" | ||
#include "dynamatic/Support/LLVM.h" | ||
#include <optional> | ||
|
||
using namespace mlir; | ||
using namespace circt; | ||
using namespace circt::handshake; | ||
using namespace dynamatic; | ||
|
||
const unsigned CPP_MAX_WIDTH = 64; | ||
const unsigned ADDRESS_WIDTH = 32; | ||
|
||
IntegerType getNewType(Value opType, unsigned bitswidth, bool signless = false); | ||
|
||
IntegerType getNewType(Value opType, unsigned bitswidth, | ||
IntegerType::SignednessSemantics ifSign); | ||
|
||
std::optional<Operation *> insertWidthMatchOp(Operation *newOp, int opInd, | ||
Type newType, MLIRContext *ctx); | ||
|
||
namespace dynamatic::update { | ||
yuxwang99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Construct the functions w.r.t. the operation name in the forward process | ||
yuxwang99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
void constructForwardFuncMap( | ||
DenseMap<StringRef, | ||
std::function<unsigned(Operation::operand_range vecOperands)>> | ||
&mapOpNameWidth); | ||
|
||
// Construct the functions w.r.t. the operation name in the backward process | ||
void constructBackwardFuncMap( | ||
DenseMap<StringRef, | ||
std::function<unsigned(Operation::result_range vecResults)>> | ||
&mapOpNameWidth); | ||
|
||
// Construct the functions w.r.t. the operation name in the validation process | ||
void constructUpdateFuncMap( | ||
DenseMap<mlir::StringRef, | ||
std::function<unsigned(Operation::operand_range vecOperands)>> | ||
&mapOpNameWidth); | ||
|
||
// Propagate the bits width of the operands to the result | ||
// For branch and conditional branch operations | ||
bool propType(Operation *Op); | ||
|
||
// Insert width match operations (extension or truncation) for the operands and | ||
// the results | ||
void matchOpResWidth(Operation *Op, MLIRContext *ctx, | ||
SmallVector<Operation *> &newMatchedOps); | ||
|
||
// Replace the operation's operand with the its successor | ||
void replaceWithSuccessor(Operation *Op); | ||
|
||
// Replace the operation's operand with the its successor | ||
// Set the operation's resultOp according to its successor's resultOp type | ||
void replaceWithSuccessor(Operation *Op, Type resType); | ||
|
||
// Validate the truncation and extension operation in case its operand and | ||
// result operand width are not consistent by reverting or deleting the | ||
// operations | ||
void revertTruncOrExt(Operation *Op, MLIRContext *ctx); | ||
|
||
// Set the validation method flags to validate the operations | ||
void setValidateType(Operation *Op, bool &passtype, bool &match, bool &revert); | ||
|
||
// Validate the operations after bits optimization to generate .mlir file | ||
void validateOp(Operation *Op, MLIRContext *ctx, | ||
SmallVector<Operation *> &newMatchedOps); | ||
} // namespace dynamatic::update | ||
|
||
#endif // DYNAMATIC_TRANSFORMS_UTILSBITSUPDATE_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//===- InitCstWidth.cpp - Reduce the constant bits width --------*- C++ -*-===// | ||
// | ||
// This file contains the implementation of the init-cstwidth pass. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "dynamatic/Transforms/InitCstWidth.h" | ||
#include "circt/Dialect/Handshake/HandshakeOps.h" | ||
#include "dynamatic/Transforms/PassDetails.h" | ||
#include "mlir/Dialect/Arith/IR/Arith.h" | ||
#include "mlir/Dialect/Func/IR/FuncOps.h" | ||
#include "mlir/IR/Dialect.h" | ||
#include "mlir/Support/LogicalResult.h" | ||
|
||
#include "mlir/IR/OperationSupport.h" | ||
#include "mlir/Support/IndentedOstream.h" | ||
|
||
static LogicalResult initCstOpBitsWidth(handshake::FuncOp funcOp, | ||
MLIRContext *ctx) { | ||
OpBuilder builder(ctx); | ||
SmallVector<handshake::ConstantOp> cstOps; | ||
|
||
int savedBits = 0; | ||
|
||
for (auto op : | ||
llvm::make_early_inc_range(funcOp.getOps<handshake::ConstantOp>())) { | ||
unsigned cstBitWidth = CPP_MAX_WIDTH; | ||
IntegerType::SignednessSemantics ifSign = | ||
IntegerType::SignednessSemantics::Signless; | ||
// skip the bool value constant operation | ||
if (isa<BoolAttr>(op.getValue())) | ||
yuxwang99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
continue; | ||
|
||
// get the attribute value | ||
if (auto intAttr = dyn_cast<mlir::IntegerAttr>(op.getValue())) { | ||
if (int cstVal = intAttr.getValue().getZExtValue(); cstVal > 0) | ||
cstBitWidth = log2(cstVal) + 2; | ||
lucas-rami marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else if (int cstVal = intAttr.getValue().getZExtValue(); cstVal < 0) { | ||
cstBitWidth = log2(-cstVal) + 2; | ||
} else | ||
cstBitWidth = 2; | ||
} | ||
|
||
if (cstBitWidth < op.getResult().getType().getIntOrFloatBitWidth()) { | ||
// Get the new type of calculated bitwidth | ||
Type newType = getNewType(op.getResult(), cstBitWidth, ifSign); | ||
|
||
// Update the constant operator for both ValueAttr and result Type | ||
builder.setInsertionPointAfter(op); | ||
handshake::ConstantOp newCstOp = builder.create<handshake::ConstantOp>( | ||
op.getLoc(), newType, op.getValue(), op.getCtrl()); | ||
|
||
// Determine the proper representation of the constant value | ||
int intVal = op.getValue().cast<IntegerAttr>().getInt(); | ||
intVal = | ||
((1 << op.getValue().getType().getIntOrFloatBitWidth()) - 1 + intVal); | ||
newCstOp.setValueAttr(IntegerAttr::get(newType, intVal)); | ||
lucas-rami marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// save the original bb | ||
newCstOp->setAttr("bb", op->getAttr("bb")); | ||
|
||
// recursively replace the uses of the old constant operation with the new | ||
// one Value opVal = op.getResult(); | ||
savedBits += | ||
op.getResult().getType().getIntOrFloatBitWidth() - cstBitWidth; | ||
auto extOp = builder.create<mlir::arith::ExtSIOp>( | ||
newCstOp.getLoc(), op.getResult().getType(), newCstOp.getResult()); | ||
|
||
// replace the constant operation (default width) | ||
// with new constant operation (optimized width) | ||
op->replaceAllUsesWith(newCstOp); | ||
yuxwang99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// update the user of constant operation | ||
SmallVector<Operation *> userOps; | ||
for (auto &user : newCstOp.getResult().getUses()) | ||
userOps.push_back(user.getOwner()); | ||
|
||
for (auto updateOp : userOps) | ||
if (!isa<mlir::arith::ExtSIOp>(*updateOp)) | ||
updateOp->replaceUsesOfWith(newCstOp.getResult(), | ||
extOp->getResult(0)); | ||
|
||
builder.clearInsertionPoint(); | ||
op->erase(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to erase the original operation. It will be taken care of by MLIR's dead-code elimination in the end. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see the operation is still remained in the handshake level .mlir file. Is it completely fine to let a dead code here? |
||
} | ||
} | ||
// llvm::errs() << "Constant saved bits " << savedBits << "\n"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feel free to use
|
||
|
||
return success(); | ||
} | ||
|
||
struct HandshakeInitCstWidthPass | ||
: public HandshakeInitCstWidthBase<HandshakeInitCstWidthPass> { | ||
|
||
void runOnOperation() override { | ||
auto *ctx = &getContext(); | ||
|
||
ModuleOp m = getOperation(); | ||
for (auto funcOp : m.getOps<handshake::FuncOp>()) | ||
if (failed(initCstOpBitsWidth(funcOp, ctx))) | ||
return signalPassFailure(); | ||
}; | ||
}; | ||
|
||
std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>> | ||
dynamatic::createInitCstWidthPass() { | ||
return std::make_unique<HandshakeInitCstWidthPass>(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
.gitignore
file should not be changed.