-
Notifications
You must be signed in to change notification settings - Fork 17
[Transform][BUG] fix gc-check fail on creating arith pass #157
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
Conversation
d35f21b
to
8416732
Compare
lib/gc/Transforms/Pipeline.cpp
Outdated
@@ -56,7 +56,7 @@ void populateVectorPasses(mlir::PassManager &pm) { | |||
pm.addNestedPass<func::FuncOp>(math::createMathLegalizeToF32()); | |||
// sourceTypeStrs can be extended | |||
arith::ArithEmulateUnsupportedFloatsOptions options; | |||
options.sourceTypeStrs = {"bf16"}; | |||
options.sourceTypeStrs = SmallVector<std::string>{"bf16"}; |
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.
What is the type of sourceTypeStrs
?
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.
::mlir::Pass::ListOption<std::string>
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.
No, I searched that:
struct ArithEmulateUnsupportedFloatsOptions {
::llvm::ArrayRef<std::string> sourceTypeStrs;
std::string targetTypeStr = "f32";
};
Your code is still dangerous. Please note that llvm::ArrayRef<std::string>
does not hold the ownership of temp value = SmallVector<std::string>{"bf16"};
, so after options.sourceTypeStrs = SmallVector<std::string>{"bf16"};
, it still point to a dead value.
Suggested:
std::string data = "bf16";
sourceTypeStrs = &data;
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.
I don't see much difference. std::string data
lives on stack and will be constructed after function returns. But we need it alive during pm.run(op)
.
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.
maybe we can use:
static ArrayRef<std::string> data = {"bf16"};
options.sourceTypeStrs = data;
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.
actually we don't need to save a SmallVector<std::string> data
. A single string is enough? Maybe ```
const static string data = "...";
options.sourceTypeStrs = {&data, 1};
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.
This is enough for now, changed.
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.
Sorry to revisit the issue here. I finally found that we only need
std::array<std::string, 1> typestr = {"bf16"};
options.sourceTypeStrs = typestr ;
Note that we don't need static
storage here.
@crazydemo is right in some way. I am sorry for misunderstanding the MLIR code. We pass the arrayref to the options struct ArithEmulateUnsupportedFloatsOptions
. And the struct is passed to createArithEmulateUnsupportedFloats
. In TD-generated source build/tools/mlir/include/mlir/Dialect/Arith/Transforms/Passes.h.inc
, we can see it calls Pass
constructor
ArithEmulateUnsupportedFloatsBase(const ArithEmulateUnsupportedFloatsOptions &options) : ArithEmulateUnsupportedFloatsBase() {
sourceTypeStrs = options.sourceTypeStrs;
targetTypeStr = options.targetTypeStr;
}
while sourceTypeStrs
is a field of ArithEmulateUnsupportedFloatsBase
of type ::mlir::Pass::ListOption<std::string> sourceTypeStrs{ ....}
ListOption
extends an ancestor class which has std::vector
to store the data. So ArithEmulateUnsupportedFloatsBase::sourceTypeStrs
copies the data from ArithEmulateUnsupportedFloatsOptions::sourceTypeStrs
, and it holds the ownership of the data. See the ancestor class:
//llvm/include/llvm/Support/CommandLine.h
template <class DataType> class list_storage<DataType, bool> {
std::vector<DataType> Storage;
std::vector<OptionValue<DataType>> Default;
bool DefaultAssigned = false;
...
};
In conclusion, we don't need a static
lifetime bf16
string here.
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.
BTW, please always avoid writing code like
ArrayRef<std::string> x = {"abc"};
somefunc(x);
Please note that "abc" has type of char[4]
which is not std::string
. The compiler inserts an conversion here, and the code looks like
ArrayRef<std::string> x = {std::string("abc")};
Also note std::string("abc")
is a temp value and the lifetime ends at the full evaluation of the statement, which means it is dead after the ;
at this line. And x
outlives the temp value and points to a dead pointer.
However, the following code is valid:
ArrayRef<const char*> x = {"abc"};
ArrayRef<StringRef> y = {"abc"};
Below also valid
void somefunc(ArrayRef<std::string> x);
....
somefunc({"bf16"});
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.
Good finding! The interface design doesn't have a problem.
9b16692
to
995d33b
Compare
995d33b
to
40c7c12
Compare
40c7c12
to
9b15f74
Compare
As Title.