Skip to content
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

[c_api] Public API for DSLX to IR w/ warning knobs. #1915

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions xls/contrib/mlir/tools/xls_translate/xls_translate_from_mlir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -984,8 +984,6 @@ FailureOr<PackageInfo> importDslxInstantiation(
::llvm::StringRef path = file_import_op.getFilename();

std::string module_name = "imported_module";
std::string_view stdlib_path = ::xls::GetDefaultDslxStdlibPath();
std::vector<std::filesystem::path> additional_search_paths = {};
absl::StatusOr<std::string> package_string_or;

// Note: this is not bullet proof. The experience if these are wrong would
Expand All @@ -1006,9 +1004,12 @@ FailureOr<PackageInfo> importDslxInstantiation(

// Note: using a different pathname here else XLS considers this a circular
// import.
package_string_or =
::xls::ConvertDslxToIr(dslx, "<instantiated module>", module_name,
stdlib_path, additional_search_paths);
const ::xls::ConvertDslxToIrOptions options{
.dslx_stdlib_path = ::xls::GetDefaultDslxStdlibPath(),
.warnings_as_errors = false,
};
package_string_or = ::xls::ConvertDslxToIr(dslx, "<instantiated module>",
module_name, options);
if (!package_string_or.ok()) {
llvm::errs() << "Failed to convert DSLX to IR: "
<< package_string_or.status().message() << "\n";
Expand Down Expand Up @@ -1769,8 +1770,12 @@ absl::StatusOr<std::shared_ptr<const Package>> DslxPackageCache::import(
if (it != cache.end()) {
return it->second;
}
absl::StatusOr<std::string> package_string_or = ::xls::ConvertDslxPathToIr(
fileName, ::xls::GetDefaultDslxStdlibPath(), {});
const ::xls::ConvertDslxToIrOptions options{
.dslx_stdlib_path = ::xls::GetDefaultDslxStdlibPath(),
.warnings_as_errors = false,
};
absl::StatusOr<std::string> package_string_or =
::xls::ConvertDslxPathToIr(fileName, options);
if (!package_string_or.ok()) {
return package_string_or.status();
}
Expand Down
4 changes: 2 additions & 2 deletions xls/dslx/ir_convert/convert_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ struct ConvertOptions {
// Should warnings be treated as errors?
bool warnings_as_errors = true;

// Set of warnings that are enabled.
// Set of warnings used in DSLX typechecking.
//
// Note that this is only used in IR conversion routines that do typechecking.
WarningKindSet enabled_warnings = kDefaultWarningsSet;
WarningKindSet warnings = kDefaultWarningsSet;

// Should #[test] and #[test_proc] entities be emitted to IR.
bool convert_tests = false;
Expand Down
6 changes: 3 additions & 3 deletions xls/dslx/ir_convert/ir_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -590,9 +590,9 @@ absl::StatusOr<PackageConversionData> ConvertFilesToPackage(
"path to know where to resolve the entry function");
}
for (std::string_view path : paths) {
ImportData import_data(CreateImportData(
stdlib_path, dslx_paths, convert_options.enabled_warnings,
std::make_unique<RealFilesystem>()));
ImportData import_data(
CreateImportData(stdlib_path, dslx_paths, convert_options.warnings,
std::make_unique<RealFilesystem>()));
XLS_ASSIGN_OR_RETURN(std::string text,
import_data.vfs().GetFileContents(path));
XLS_ASSIGN_OR_RETURN(std::string module_name, PathToName(path));
Expand Down
2 changes: 1 addition & 1 deletion xls/dslx/ir_convert/ir_converter_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ absl::Status RealMain(absl::Span<const std::string_view> paths) {
.emit_fail_as_assert = emit_fail_as_assert,
.verify_ir = verify_ir,
.warnings_as_errors = warnings_as_errors,
.enabled_warnings = warnings,
.warnings = warnings,
.convert_tests = convert_tests,
.default_fifo_config = default_fifo_config,
};
Expand Down
2 changes: 1 addition & 1 deletion xls/dslx/run_routines/ir_test_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ absl::StatusOr<std::unique_ptr<AbstractParsedTestRunner>> MakeRunner(
.emit_fail_as_assert = true,
.verify_ir = false,
.warnings_as_errors = false,
.enabled_warnings = kNoWarningsSet,
.warnings = kNoWarningsSet,
.convert_tests = true,
};
absl::flat_hash_map<std::string, std::unique_ptr<Package>> packages;
Expand Down
2 changes: 2 additions & 0 deletions xls/dslx/warning_collector.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class WarningCollector {

const std::vector<Entry>& warnings() const { return warnings_; }

bool empty() const { return warnings_.empty(); }

private:
const WarningKindSet enabled_;
std::vector<Entry> warnings_;
Expand Down
126 changes: 110 additions & 16 deletions xls/public/c_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,39 +58,119 @@ void xls_init_xls(const char* usage, int argc, char* argv[]) {
(void)(xls::InitXls(usage, argc, argv));
}

bool xls_convert_dslx_to_ir_with_warnings(
const char* dslx, const char* path, const char* module_name,
const char* dslx_stdlib_path, const char* additional_search_paths[],
size_t additional_search_paths_count, const char* enable_warnings[],
size_t enable_warnings_count, const char* disable_warnings[],
size_t disable_warnings_count, bool warnings_as_errors,
char*** warnings_out, size_t* warnings_out_count, char** error_out,
char** ir_out) {
CHECK(dslx != nullptr);
CHECK(path != nullptr);
CHECK(dslx_stdlib_path != nullptr);
CHECK(error_out != nullptr);

std::vector<std::filesystem::path> additional_search_paths_cpp =
xls::ToCppPaths(additional_search_paths, additional_search_paths_count);
std::vector<std::string_view> enable_warnings_cpp =
xls::ToCppStringViews(enable_warnings, enable_warnings_count);
std::vector<std::string_view> disable_warnings_cpp =
xls::ToCppStringViews(disable_warnings, disable_warnings_count);

std::vector<std::string> warnings_out_cpp;

const xls::ConvertDslxToIrOptions options = {
.dslx_stdlib_path = dslx_stdlib_path,
.additional_search_paths = additional_search_paths_cpp,
.enable_warnings = enable_warnings_cpp,
.disable_warnings = disable_warnings_cpp,
.warnings_as_errors = warnings_as_errors,
.warnings_out = &warnings_out_cpp,
};

absl::StatusOr<std::string> result =
xls::ConvertDslxToIr(dslx, path, module_name, options);

if (warnings_out != nullptr) {
xls::ToOwnedCStrings(warnings_out_cpp, warnings_out, warnings_out_count);
} else if (warnings_out_count != nullptr) {
*warnings_out_count = warnings_out_cpp.size();
}

return xls::ReturnStringHelper(result, error_out, ir_out);
}

bool xls_convert_dslx_to_ir(const char* dslx, const char* path,
const char* module_name,
const char* dslx_stdlib_path,
const char* additional_search_paths[],
size_t additional_search_paths_count,
char** error_out, char** ir_out) {
CHECK(dslx != nullptr);
const char* enable_warnings[] = {};
const char* disable_warnings[] = {};
return xls_convert_dslx_to_ir_with_warnings(
dslx, path, module_name, dslx_stdlib_path, additional_search_paths,
additional_search_paths_count, enable_warnings, 0, disable_warnings, 0,
/*warnings_as_errors=*/false,
/*warnings_out=*/nullptr,
/*warnings_out_count=*/nullptr, error_out, ir_out);
}

bool xls_convert_dslx_path_to_ir_with_warnings(
const char* path, const char* dslx_stdlib_path,
const char* additional_search_paths[], size_t additional_search_paths_count,
const char* enable_warnings[], size_t enable_warnings_count,
const char* disable_warnings[], size_t disable_warnings_count,
bool warnings_as_errors, char*** warnings_out, size_t* warnings_out_count,
char** error_out, char** ir_out) {
CHECK(path != nullptr);
CHECK(dslx_stdlib_path != nullptr);
CHECK(error_out != nullptr);
if (warnings_out != nullptr) {
CHECK(warnings_out_count != nullptr);
}

std::vector<std::filesystem::path> additional_search_paths_cpp =
xls::ToCpp(additional_search_paths, additional_search_paths_count);
xls::ToCppPaths(additional_search_paths, additional_search_paths_count);
std::vector<std::string_view> enable_warnings_cpp =
xls::ToCppStringViews(enable_warnings, enable_warnings_count);
std::vector<std::string_view> disable_warnings_cpp =
xls::ToCppStringViews(disable_warnings, disable_warnings_count);

std::vector<std::string> warnings_out_cpp;

const xls::ConvertDslxToIrOptions options = {
.dslx_stdlib_path = dslx_stdlib_path,
.additional_search_paths = additional_search_paths_cpp,
.enable_warnings = enable_warnings_cpp,
.disable_warnings = disable_warnings_cpp,
.warnings_as_errors = warnings_as_errors,
.warnings_out = &warnings_out_cpp,
};
absl::StatusOr<std::string> result = xls::ConvertDslxPathToIr(path, options);

if (warnings_out != nullptr) {
xls::ToOwnedCStrings(warnings_out_cpp, warnings_out, warnings_out_count);
} else if (warnings_out_count != nullptr) {
*warnings_out_count = warnings_out_cpp.size();
}

absl::StatusOr<std::string> result = xls::ConvertDslxToIr(
dslx, path, module_name, dslx_stdlib_path, additional_search_paths_cpp);
return xls::ReturnStringHelper(result, error_out, ir_out);
}

bool xls_convert_dslx_path_to_ir(const char* path, const char* dslx_stdlib_path,
const char* additional_search_paths[],
size_t additional_search_paths_count,
char** error_out, char** ir_out) {
CHECK(path != nullptr);
CHECK(dslx_stdlib_path != nullptr);
CHECK(error_out != nullptr);

std::vector<std::filesystem::path> additional_search_paths_cpp =
xls::ToCpp(additional_search_paths, additional_search_paths_count);

absl::StatusOr<std::string> result = xls::ConvertDslxPathToIr(
path, dslx_stdlib_path, additional_search_paths_cpp);
return xls::ReturnStringHelper(result, error_out, ir_out);
const char* enable_warnings[] = {};
const char* disable_warnings[] = {};
return xls_convert_dslx_path_to_ir_with_warnings(
path, dslx_stdlib_path, additional_search_paths,
additional_search_paths_count, enable_warnings, 0, disable_warnings, 0,
/*warnings_as_errors=*/false,
/*warnings_out=*/nullptr,
/*warnings_out_count=*/nullptr, error_out, ir_out);
}

bool xls_optimize_ir(const char* ir, const char* top, char** error_out,
Expand Down Expand Up @@ -461,8 +541,22 @@ void xls_package_free(struct xls_package* p) {
delete reinterpret_cast<xls::Package*>(p);
}

void xls_c_str_free(char* c_str) {
free(c_str);
void xls_c_str_free(char* c_str) { free(c_str); }

void xls_c_strs_free(char** c_strs, size_t count) {
CHECK_EQ(count == 0, c_strs == nullptr) << absl::StreamFormat(
"xls_c_strs_free expected consistency between zero-size and "
"array being nullptr; count = %d, c_strs = %p",
count, c_strs);

if (c_strs == nullptr) {
return;
}

for (size_t i = 0; i < count; ++i) {
free(c_strs[i]);
}
delete[] c_strs;
}

bool xls_value_to_string(const struct xls_value* v, char** string_out) {
Expand Down
31 changes: 31 additions & 0 deletions xls/public/c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,39 @@ bool xls_convert_dslx_to_ir(const char* dslx, const char* path,
size_t additional_search_paths_count,
char** error_out, char** ir_out);

// As above, but also takes `enable_warnings` and `disable_warnings` which
// are arrays of warning names to enable or disable respectively against the
// default warning set.
//
// Precondition: if `warnings_out` is provided then `warnings_out_count` must
// also be provided.
//
// Note that if the `warnings_out_count` is populated with zero (i.e. there were
// no warnings) then we can return `nullptr` for `warnings_out`.
bool xls_convert_dslx_to_ir_with_warnings(
const char* dslx, const char* path, const char* module_name,
const char* dslx_stdlib_path, const char* additional_search_paths[],
size_t additional_search_paths_count, const char* enable_warnings[],
size_t enable_warnings_count, const char* disable_warnings[],
grebe marked this conversation as resolved.
Show resolved Hide resolved
size_t disable_warnings_count, bool warnings_as_errors,
char*** warnings_out, size_t* warnings_out_count, char** error_out,
char** ir_out);

bool xls_convert_dslx_path_to_ir(const char* path, const char* dslx_stdlib_path,
const char* additional_search_paths[],
size_t additional_search_paths_count,
char** error_out, char** ir_out);

// As above `xls_convert_dslx_to_ir_with_warnings`, but for a filesystem path
// instead of DSLX text.
bool xls_convert_dslx_path_to_ir_with_warnings(
const char* path, const char* dslx_stdlib_path,
const char* additional_search_paths[], size_t additional_search_paths_count,
const char* enable_warnings[], size_t enable_warnings_count,
const char* disable_warnings[], size_t disable_warnings_count,
bool warnings_as_errors, char*** warnings_out, size_t* warnings_out_count,
char** error_out, char** ir_out);

bool xls_optimize_ir(const char* ir, const char* top, char** error_out,
char** ir_out);

Expand Down Expand Up @@ -237,6 +265,9 @@ void xls_package_free(struct xls_package* p);
// just call `free` directly).
void xls_c_str_free(char* c_str);

// Frees an array of C strings that were provided by this XLS public API.
void xls_c_strs_free(char** c_strs, size_t count);

// Returns a string representation of the given IR package `p`.
bool xls_package_to_string(const struct xls_package* p, char** string_out);

Expand Down
2 changes: 1 addition & 1 deletion xls/public/c_api_dslx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct xls_dslx_import_data* xls_dslx_import_data_create(
size_t additional_search_paths_count) {
std::filesystem::path cpp_stdlib_path{dslx_stdlib_path};
std::vector<std::filesystem::path> cpp_additional_search_paths =
xls::ToCpp(additional_search_paths, additional_search_paths_count);
xls::ToCppPaths(additional_search_paths, additional_search_paths_count);
xls::dslx::ImportData import_data = CreateImportData(
cpp_stdlib_path, cpp_additional_search_paths, xls::dslx::kAllWarningsSet,
std::make_unique<xls::dslx::RealFilesystem>());
Expand Down
38 changes: 34 additions & 4 deletions xls/public/c_api_impl_helpers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@

namespace xls {

std::vector<std::filesystem::path> ToCpp(const char* additional_search_paths[],
size_t additional_search_paths_count) {
std::vector<std::filesystem::path> ToCppPaths(
const char* additional_search_paths[],
size_t additional_search_paths_count) {
std::vector<std::filesystem::path> additional_search_paths_cpp;
additional_search_paths_cpp.reserve(additional_search_paths_count);
for (size_t i = 0; i < additional_search_paths_count; ++i) {
Expand All @@ -41,10 +42,39 @@ std::vector<std::filesystem::path> ToCpp(const char* additional_search_paths[],
return additional_search_paths_cpp;
}

std::vector<std::string_view> ToCppStringViews(const char* strings[],
size_t strings_count) {
std::vector<std::string_view> strings_cpp;
strings_cpp.reserve(strings_count);
for (size_t i = 0; i < strings_count; ++i) {
const char* string = strings[i];
CHECK(string != nullptr);
strings_cpp.push_back(string);
}
return strings_cpp;
}

char* ToOwnedCString(std::string_view s) { return strndup(s.data(), s.size()); }

// Helper function that we can use to adapt to the common C API pattern when
// we're returning an `absl::StatusOr<std::string>` value.
void ToOwnedCStrings(absl::Span<const std::string> cpp, char*** c_out,
size_t* c_out_count) {
CHECK(c_out != nullptr);
CHECK(c_out_count != nullptr);

// For the empty array case we avoid a needless zero-sized allocation.
if (cpp.empty()) {
*c_out = nullptr;
*c_out_count = 0;
return;
}

*c_out = new char*[cpp.size()];
cdleary marked this conversation as resolved.
Show resolved Hide resolved
*c_out_count = cpp.size();
for (size_t i = 0; i < cpp.size(); ++i) {
(*c_out)[i] = ToOwnedCString(cpp[i]);
}
}

bool ReturnStringHelper(absl::StatusOr<std::string>& to_return,
char** error_out, char** value_out) {
if (to_return.ok()) {
Expand Down
19 changes: 17 additions & 2 deletions xls/public/c_api_impl_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,25 @@ bool ReturnStringHelper(absl::StatusOr<std::string>& to_return,
// caller.
char* ToOwnedCString(std::string_view s);

// Converts a C++ vector of strings into a C array of strings and a count of the
// number of strings.
//
// Precondition: `c_out` and `c_out_count` must not be `nullptr`.
//
// Note: if the `cpp` span is empty, then `c_out` will be set to a `nullptr`
// (and `c_out_count` will be set to 0) so callers should not rely on the value
// of `c_out` to determine if the conversion was successful.
void ToOwnedCStrings(absl::Span<const std::string> cpp, char*** c_out,
size_t* c_out_count);

// Converts the C representation of filesystem search paths into a C++
// representation.
std::vector<std::filesystem::path> ToCpp(const char* additional_search_paths[],
size_t additional_search_paths_count);
std::vector<std::filesystem::path> ToCppPaths(const char* paths[],
size_t paths_count);

// Converts the C representation of warnings into a C++ representation.
std::vector<std::string_view> ToCppStringViews(const char* strings[],
size_t strings_count);

} // namespace xls

Expand Down
Loading
Loading