From 302211cdc5da0528f80596ad7ebbca687e025cab Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 10 Feb 2023 10:01:03 -0800 Subject: [PATCH 1/4] Tiny improvements in codegen in C backend (1) Emit `true` or `false` instead of `(bool)(0ull)` etc for bool literals (2) Avoid redundant temporaries in print_cast_expr(), which occur in a small but nonzero number of cases Basically this means that code currently like ``` bool _523 = (bool)(0ull); bool _524 = (bool)(_523); ... foo(_524); ``` becomes ``` foo(false); ``` ...I'm sure this has no output on final object code, but it makes the generated C code less weird to read. --- src/CodeGen_C.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/CodeGen_C.cpp b/src/CodeGen_C.cpp index 7bf7bc0df7e5..750956e1dd89 100644 --- a/src/CodeGen_C.cpp +++ b/src/CodeGen_C.cpp @@ -2201,6 +2201,10 @@ string CodeGen_C::print_expr(const Expr &e) { string CodeGen_C::print_cast_expr(const Type &t, const Expr &e) { string value = print_expr(e); + if (e.type() == t) { + // This is uncommon but does happen occasionally + return value; + } string type = print_type(t); if (t.is_vector() && t.lanes() == e.type().lanes() && @@ -2405,12 +2409,16 @@ void CodeGen_C::visit(const IntImm *op) { } void CodeGen_C::visit(const UIntImm *op) { - static const char *const suffixes[3] = { - "ull", // PlainC - "ul", // OpenCL - "", // HLSL - }; - print_assignment(op->type, "(" + print_type(op->type) + ")(" + std::to_string(op->value) + suffixes[(int)integer_suffix_style] + ")"); + if (op->type == UInt(1)) { + id = op->value ? "true" : "false"; + } else { + static const char *const suffixes[3] = { + "ull", // PlainC + "ul", // OpenCL + "", // HLSL + }; + print_assignment(op->type, "static_cast<" + print_type(op->type) + ">(" + std::to_string(op->value) + suffixes[(int)integer_suffix_style] + ")"); + } } void CodeGen_C::visit(const StringImm *op) { From d467ff0a1b12fbafbc3760afe8523ea72410ad64 Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 10 Feb 2023 10:50:04 -0800 Subject: [PATCH 2/4] Also avoid extra intermediates for typed nullptr --- src/CodeGen_C.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/CodeGen_C.cpp b/src/CodeGen_C.cpp index 750956e1dd89..d67ba41ec2c5 100644 --- a/src/CodeGen_C.cpp +++ b/src/CodeGen_C.cpp @@ -1384,7 +1384,19 @@ string CodeGen_C::print_reinterpret(Type type, const Expr &e) { } else { oss << "reinterpret<" << print_type(type) << ">"; } - oss << "(" << print_expr(e) << ")"; + // If we are generating a typed nullptr, just emit that as a literal, with no intermediate, + // to avoid ugly code like + // + // uint64_t _32 = static_cast(0ull); + // auto *_33 = (void *)(_32); + // + // and instead just do + // auto *_33 = (void *)(nullptr); + if (type.is_handle() && is_const_zero(e)) { + oss << "(nullptr)"; + } else { + oss << "(" << print_expr(e) << ")"; + } return oss.str(); } From 3c74867ebd35c4c8ca3cfbde1d415697a0cf87e3 Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 10 Feb 2023 10:53:49 -0800 Subject: [PATCH 3/4] Also use std::isnan() and std::isinf() --- src/CodeGen_C.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/CodeGen_C.cpp b/src/CodeGen_C.cpp index d67ba41ec2c5..6e1344ef30d1 100644 --- a/src/CodeGen_C.cpp +++ b/src/CodeGen_C.cpp @@ -2439,24 +2439,10 @@ void CodeGen_C::visit(const StringImm *op) { id = oss.str(); } -// NaN is the only float/double for which this is true... and -// surprisingly, there doesn't seem to be a portable isnan function -// (dsharlet). -template -static bool isnan(T x) { - return x != x; -} - -template -static bool isinf(T x) { - return std::numeric_limits::has_infinity && (x == std::numeric_limits::infinity() || - x == -std::numeric_limits::infinity()); -} - void CodeGen_C::visit(const FloatImm *op) { - if (isnan(op->value)) { + if (std::isnan(op->value)) { id = "nan_f32()"; - } else if (isinf(op->value)) { + } else if (std::isinf(op->value)) { if (op->value > 0) { id = "inf_f32()"; } else { From 72720c985985cc97f9f7c6db810e9580874e5a65 Mon Sep 17 00:00:00 2001 From: Steven Johnson Date: Fri, 10 Feb 2023 13:14:41 -0800 Subject: [PATCH 4/4] Update CodeGen_C.cpp --- src/CodeGen_C.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CodeGen_C.cpp b/src/CodeGen_C.cpp index 6e1344ef30d1..9d7e437136e7 100644 --- a/src/CodeGen_C.cpp +++ b/src/CodeGen_C.cpp @@ -1387,7 +1387,7 @@ string CodeGen_C::print_reinterpret(Type type, const Expr &e) { // If we are generating a typed nullptr, just emit that as a literal, with no intermediate, // to avoid ugly code like // - // uint64_t _32 = static_cast(0ull); + // uint64_t _32 = (uint64_t)(0ull); // auto *_33 = (void *)(_32); // // and instead just do @@ -2429,7 +2429,7 @@ void CodeGen_C::visit(const UIntImm *op) { "ul", // OpenCL "", // HLSL }; - print_assignment(op->type, "static_cast<" + print_type(op->type) + ">(" + std::to_string(op->value) + suffixes[(int)integer_suffix_style] + ")"); + print_assignment(op->type, "(" + print_type(op->type) + ")(" + std::to_string(op->value) + suffixes[(int)integer_suffix_style] + ")"); } }