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

Trim code size for Printer #6473

Closed
wants to merge 6 commits into from
Closed
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
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,7 @@ RUNTIME_CPP_COMPONENTS = \
posix_threads_tsan \
powerpc_cpu_features \
prefetch \
printer \
profiler \
profiler_inlined \
pseudostack \
Expand Down
3 changes: 3 additions & 0 deletions src/LLVM_Runtime_Linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ DECLARE_CPP_INITMOD(posix_print)
DECLARE_CPP_INITMOD(posix_threads)
DECLARE_CPP_INITMOD(posix_threads_tsan)
DECLARE_CPP_INITMOD(prefetch)
DECLARE_CPP_INITMOD(printer)
DECLARE_CPP_INITMOD(profiler)
DECLARE_CPP_INITMOD(profiler_inlined)
DECLARE_CPP_INITMOD(pseudostack)
Expand Down Expand Up @@ -1111,8 +1112,10 @@ std::unique_ptr<llvm::Module> get_initial_module_for_target(Target t, llvm::LLVM

if (module_type == ModuleJITShared || module_type == ModuleGPU) {
modules.push_back(get_initmod_module_jit_ref_count(c, bits_64, debug));
modules.push_back(get_initmod_printer(c, bits_64, debug));
} else if (module_type == ModuleAOT) {
modules.push_back(get_initmod_module_aot_ref_count(c, bits_64, debug));
modules.push_back(get_initmod_printer(c, bits_64, debug));
}

if (module_type == ModuleAOT || module_type == ModuleGPU) {
Expand Down
5 changes: 3 additions & 2 deletions src/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,9 +711,10 @@ std::map<Output, std::string> compile_standalone_runtime(const std::map<Output,

Module empty("standalone_runtime", t.without_feature(Target::NoRuntime).without_feature(Target::JIT));
// For runtime, it only makes sense to output object files or static_library, so ignore
// everything else.
// everything else. (Well, LLVM IR and actual assembly can be useful for debugging and optimzation
// as well, so let's allow that, too.)
std::map<Output, std::string> actual_outputs;
for (auto key : {Output::object, Output::static_library}) {
for (auto key : {Output::object, Output::static_library, Output::llvm_assembly, Output::assembly}) {
auto it = output_files.find(key);
if (it != output_files.end()) {
actual_outputs[key] = it->second;
Expand Down
1 change: 1 addition & 0 deletions src/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ set(RUNTIME_CPP
posix_threads_tsan
powerpc_cpu_features
prefetch
printer
profiler
profiler_inlined
pseudostack
Expand Down
134 changes: 134 additions & 0 deletions src/runtime/printer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include "printer.h"
#include "HalideRuntime.h"

namespace Halide {
namespace Runtime {
namespace Internal {

static const char *const kAllocationError = "Printer buffer allocation failed.\n";

PrinterBase::PrinterBase(void *ctx, char *mem, uint64_t length)
: user_context(ctx), length(length) {

if (mem == nullptr) {
mem = (char *)malloc(length);
mem_to_free = mem;
} else {
mem_to_free = nullptr;
}

dst = buf = mem;
if (dst) {
end = buf + length - 1;
*end = 0;
} else {
end = dst;
}
}

PrinterBase::PrinterBase(void *ctx)
: PrinterBase(ctx, nullptr, default_printer_buffer_length) {
}

PrinterBase &PrinterBase::operator<<(const char *arg) {
dst = halide_string_to_string(dst, end, arg);
return *this;
}

PrinterBase &PrinterBase::operator<<(int64_t arg) {
dst = halide_int64_to_string(dst, end, arg, 1);
return *this;
}

PrinterBase &PrinterBase::operator<<(int32_t arg) {
dst = halide_int64_to_string(dst, end, arg, 1);
return *this;
}

PrinterBase &PrinterBase::operator<<(uint64_t arg) {
dst = halide_uint64_to_string(dst, end, arg, 1);
return *this;
}

PrinterBase &PrinterBase::operator<<(uint32_t arg) {
dst = halide_uint64_to_string(dst, end, arg, 1);
return *this;
}

PrinterBase &PrinterBase::operator<<(double arg) {
dst = halide_double_to_string(dst, end, arg, 1);
return *this;
}

PrinterBase &PrinterBase::operator<<(float arg) {
dst = halide_double_to_string(dst, end, arg, 0);
return *this;
}

PrinterBase &PrinterBase::operator<<(const void *arg) {
dst = halide_pointer_to_string(dst, end, arg);
return *this;
}

PrinterBase &PrinterBase::write_float16_from_bits(const uint16_t arg) {
double value = halide_float16_bits_to_double(arg);
dst = halide_double_to_string(dst, end, value, 1);
return *this;
}

PrinterBase &PrinterBase::operator<<(const halide_type_t &t) {
dst = halide_type_to_string(dst, end, &t);
return *this;
}

PrinterBase &PrinterBase::operator<<(const halide_buffer_t &buf) {
dst = halide_buffer_to_string(dst, end, &buf);
return *this;
}

// Use it like a stringstream.
const char *PrinterBase::str() {
if (!buf) {
return kAllocationError;
}

// This is really only needed for StringStreamPrinter, but is easier to do unconditionally
halide_msan_annotate_memory_is_initialized(user_context, buf, dst - buf + 1);
return buf;
}

// Clear it. Useful for reusing a stringstream.
void PrinterBase::clear() {
dst = buf;
if (dst) {
dst[0] = 0;
}
}

// Delete the last N characters
void PrinterBase::erase(int n) {
if (dst) {
dst -= n;
if (dst < buf) {
dst = buf;
}
dst[0] = 0;
}
}

PrinterBase::~PrinterBase() {
// free() is fine to call on a nullptr
free(mem_to_free);
}

void PrinterBase::finish_error() {
halide_error(user_context, str());
}

void PrinterBase::finish_print() {
halide_print(user_context, str());
}

} // namespace Internal
} // namespace Runtime
} // namespace Halide
Loading