Commit 415d1815 by Antonio Maiorano

Fix rr::Print and add unit tests

* CMake: add REACTOR_ENABLE_PRINT to enable rr::Print macros (default 0). When enabled, defines ENABLE_RR_PRINT. Formerly, ENABLE_RR_PRINT was only defined in NDEBUG builds. * CMake: REACTOR_EMIT_PRINT_LOCATION enables REACTOR_ENABLE_PRINT. * Add missing includes of Print.hpp. * Fix rr::Print compilation of non-const pointers. * Fix rr::Print compilation of Int2 and UInt2. * Fix rr::Print of Float outputting in square brackets. * Fix rr::Print of Bool to output a '1' or '0' for 'true' and 'false'. * Add unit tests for rr::Print of all primitive and Reactor types. * Includes changes bclayton@ made to output "true"/"false" for Bool, and to correctly compare against implementation-specific printf of pointers. Bug: b/149328074 Change-Id: Ibb17985201f1c2b432539cd1153293d1e1cbb5bb Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/41108Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Tested-by: 's avatarAntonio Maiorano <amaiorano@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent ac4e1d23
...@@ -120,6 +120,7 @@ option_if_not_defined(SWIFTSHADER_WARNINGS_AS_ERRORS "Treat all warnings as erro ...@@ -120,6 +120,7 @@ option_if_not_defined(SWIFTSHADER_WARNINGS_AS_ERRORS "Treat all warnings as erro
option_if_not_defined(SWIFTSHADER_DCHECK_ALWAYS_ON "Check validation macros even in release builds" 0) option_if_not_defined(SWIFTSHADER_DCHECK_ALWAYS_ON "Check validation macros even in release builds" 0)
option_if_not_defined(REACTOR_EMIT_DEBUG_INFO "Emit debug info for JIT functions" 0) option_if_not_defined(REACTOR_EMIT_DEBUG_INFO "Emit debug info for JIT functions" 0)
option_if_not_defined(REACTOR_EMIT_PRINT_LOCATION "Emit printing of location info for JIT functions" 0) option_if_not_defined(REACTOR_EMIT_PRINT_LOCATION "Emit printing of location info for JIT functions" 0)
option_if_not_defined(REACTOR_ENABLE_PRINT "Enable RR_PRINT macros" 0)
option_if_not_defined(REACTOR_VERIFY_LLVM_IR "Check reactor-generated LLVM IR is valid even in release builds" 0) option_if_not_defined(REACTOR_VERIFY_LLVM_IR "Check reactor-generated LLVM IR is valid even in release builds" 0)
option_if_not_defined(SWIFTSHADER_LESS_DEBUG_INFO "Generate less debug info to reduce file size" 0) option_if_not_defined(SWIFTSHADER_LESS_DEBUG_INFO "Generate less debug info to reduce file size" 0)
option_if_not_defined(SWIFTSHADER_ENABLE_VULKAN_DEBUGGER "Enable vulkan debugger support" 0) option_if_not_defined(SWIFTSHADER_ENABLE_VULKAN_DEBUGGER "Enable vulkan debugger support" 0)
...@@ -543,8 +544,9 @@ else() ...@@ -543,8 +544,9 @@ else()
endif() endif()
if(REACTOR_EMIT_PRINT_LOCATION) if(REACTOR_EMIT_PRINT_LOCATION)
# This feature depends on REACTOR_EMIT_DEBUG_INFO, so enable it # This feature depends on REACTOR_EMIT_DEBUG_INFO and REACTOR_ENABLE_PRINT
set(REACTOR_EMIT_DEBUG_INFO "On") set(REACTOR_EMIT_DEBUG_INFO "On")
set(REACTOR_ENABLE_PRINT "On")
list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_EMIT_PRINT_LOCATION") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_EMIT_PRINT_LOCATION")
endif() endif()
...@@ -553,6 +555,10 @@ if(REACTOR_EMIT_DEBUG_INFO) ...@@ -553,6 +555,10 @@ if(REACTOR_EMIT_DEBUG_INFO)
list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_DEBUG_INFO") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_DEBUG_INFO")
endif() endif()
if(REACTOR_ENABLE_PRINT)
list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_PRINT")
endif()
if(REACTOR_VERIFY_LLVM_IR) if(REACTOR_VERIFY_LLVM_IR)
list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_LLVM_IR_VERIFICATION") list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_LLVM_IR_VERIFICATION")
endif() endif()
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "Debug.hpp" #include "Debug.hpp"
#include "EmulatedReactor.hpp" #include "EmulatedReactor.hpp"
#include "LLVMReactorDebugInfo.hpp" #include "LLVMReactorDebugInfo.hpp"
#include "Print.hpp"
#include "Reactor.hpp" #include "Reactor.hpp"
#include "x86.hpp" #include "x86.hpp"
...@@ -3874,6 +3875,13 @@ static std::vector<Value *> toDouble(const std::vector<Value *> &vals) ...@@ -3874,6 +3875,13 @@ static std::vector<Value *> toDouble(const std::vector<Value *> &vals)
return elements; return elements;
} }
std::vector<Value *> PrintValue::Ty<Bool>::val(const RValue<Bool> &v)
{
auto t = jit->builder->CreateGlobalStringPtr("true");
auto f = jit->builder->CreateGlobalStringPtr("false");
return { V(jit->builder->CreateSelect(V(v.value), t, f)) };
}
std::vector<Value *> PrintValue::Ty<Byte>::val(const RValue<Byte> &v) std::vector<Value *> PrintValue::Ty<Byte>::val(const RValue<Byte> &v)
{ {
return toInt({ v.value }, false); return toInt({ v.value }, false);
...@@ -3965,7 +3973,7 @@ void Printv(const char *function, const char *file, int line, const char *fmt, s ...@@ -3965,7 +3973,7 @@ void Printv(const char *function, const char *file, int line, const char *fmt, s
if(function != nullptr) { str += "%s "; } if(function != nullptr) { str += "%s "; }
str += fmt; str += fmt;
// Perform subsitution on all '{n}' bracketed indices in the format // Perform substitution on all '{n}' bracketed indices in the format
// message. // message.
int i = 0; int i = 0;
for(const PrintValue &arg : args) for(const PrintValue &arg : args)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
# include "LLVMReactor.hpp" # include "LLVMReactor.hpp"
# include "Reactor.hpp" # include "Reactor.hpp"
# include "Print.hpp"
# include "boost/stacktrace.hpp" # include "boost/stacktrace.hpp"
......
...@@ -15,10 +15,6 @@ ...@@ -15,10 +15,6 @@
#ifndef rr_Print_hpp #ifndef rr_Print_hpp
#define rr_Print_hpp #define rr_Print_hpp
#if !defined(NDEBUG)
# define ENABLE_RR_PRINT 1 // Enables RR_PRINT(), RR_WATCH()
#endif // !defined(NDEBUG)
#ifdef ENABLE_RR_PRINT #ifdef ENABLE_RR_PRINT
# include "Reactor.hpp" # include "Reactor.hpp"
...@@ -147,9 +143,12 @@ public: ...@@ -147,9 +143,12 @@ public:
PrintValue(double v) PrintValue(double v)
: format(std::to_string(v)) : format(std::to_string(v))
{} {}
PrintValue(const char *v)
: format(v)
{}
template<typename T> template<typename T>
PrintValue(const T *v) PrintValue(T *v)
: format(addr(v)) : format(addr(v))
{} {}
...@@ -226,8 +225,8 @@ struct PrintValue::Ty<std::string> ...@@ -226,8 +225,8 @@ struct PrintValue::Ty<std::string>
template<> template<>
struct PrintValue::Ty<Bool> struct PrintValue::Ty<Bool>
{ {
static std::string fmt(const RValue<Bool> &v) { return "%d"; } static std::string fmt(const RValue<Bool> &v) { return "%s"; }
static std::vector<Value *> val(const RValue<Bool> &v) { return { v.value }; } static std::vector<Value *> val(const RValue<Bool> &v);
}; };
template<> template<>
struct PrintValue::Ty<Byte> struct PrintValue::Ty<Byte>
...@@ -250,7 +249,7 @@ struct PrintValue::Ty<Int> ...@@ -250,7 +249,7 @@ struct PrintValue::Ty<Int>
template<> template<>
struct PrintValue::Ty<Int2> struct PrintValue::Ty<Int2>
{ {
static std::string fmt(const RValue<Int> &v) { return "[%d, %d]"; } static std::string fmt(const RValue<Int2> &v) { return "[%d, %d]"; }
static std::vector<Value *> val(const RValue<Int2> &v); static std::vector<Value *> val(const RValue<Int2> &v);
}; };
template<> template<>
...@@ -268,7 +267,7 @@ struct PrintValue::Ty<UInt> ...@@ -268,7 +267,7 @@ struct PrintValue::Ty<UInt>
template<> template<>
struct PrintValue::Ty<UInt2> struct PrintValue::Ty<UInt2>
{ {
static std::string fmt(const RValue<UInt> &v) { return "[%u, %u]"; } static std::string fmt(const RValue<UInt2> &v) { return "[%u, %u]"; }
static std::vector<Value *> val(const RValue<UInt2> &v); static std::vector<Value *> val(const RValue<UInt2> &v);
}; };
template<> template<>
...@@ -304,7 +303,7 @@ struct PrintValue::Ty<UShort4> ...@@ -304,7 +303,7 @@ struct PrintValue::Ty<UShort4>
template<> template<>
struct PrintValue::Ty<Float> struct PrintValue::Ty<Float>
{ {
static std::string fmt(const RValue<Float> &v) { return "[%f]"; } static std::string fmt(const RValue<Float> &v) { return "%f"; }
static std::vector<Value *> val(const RValue<Float> &v); static std::vector<Value *> val(const RValue<Float> &v);
}; };
template<> template<>
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#include "Coroutine.hpp" #include "Coroutine.hpp"
#include "Print.hpp"
#include "Reactor.hpp" #include "Reactor.hpp"
#include "gtest/gtest.h" #include "gtest/gtest.h"
...@@ -107,6 +108,206 @@ int reference(int *p, int y) ...@@ -107,6 +108,206 @@ int reference(int *p, int y)
return sum; return sum;
} }
class StdOutCapture
{
public:
~StdOutCapture()
{
stopIfCapturing();
}
void start()
{
stopIfCapturing();
capturing = true;
testing::internal::CaptureStdout();
}
std::string stop()
{
assert(capturing);
capturing = false;
return testing::internal::GetCapturedStdout();
}
private:
void stopIfCapturing()
{
if(capturing)
{
// This stops the capture
testing::internal::GetCapturedStdout();
}
}
bool capturing = false;
};
std::vector<std::string> split(const std::string &s)
{
std::vector<std::string> result;
std::istringstream iss(s);
for(std::string line; std::getline(iss, line);)
{
result.push_back(line);
}
return result;
}
TEST(ReactorUnitTests, PrintPrimitiveTypes)
{
#ifdef ENABLE_RR_PRINT
FunctionT<void()> function;
{
bool b(true);
int8_t i8(-1);
uint8_t ui8(1);
int16_t i16(-1);
uint16_t ui16(1);
int32_t i32(-1);
uint32_t ui32(1);
int64_t i64(-1);
uint64_t ui64(1);
float f(1);
double d(2);
const char *cstr = "const char*";
std::string str = "std::string";
int *p = nullptr;
RR_WATCH(b);
RR_WATCH(i8);
RR_WATCH(ui8);
RR_WATCH(i16);
RR_WATCH(ui16);
RR_WATCH(i32);
RR_WATCH(ui32);
RR_WATCH(i64);
RR_WATCH(ui64);
RR_WATCH(f);
RR_WATCH(d);
RR_WATCH(cstr);
RR_WATCH(str);
RR_WATCH(p);
}
auto routine = function("one");
char pNullptr[64];
snprintf(pNullptr, sizeof(pNullptr), " p: %p", nullptr);
const char *expected[] = {
" b: true",
" i8: -1",
" ui8: 1",
" i16: -1",
" ui16: 1",
" i32: -1",
" ui32: 1",
" i64: -1",
" ui64: 1",
" f: 1.000000",
" d: 2.000000",
" cstr: const char*",
" str: std::string",
pNullptr,
};
constexpr size_t expectedSize = sizeof(expected) / sizeof(expected[0]);
StdOutCapture capture;
capture.start();
routine();
auto output = split(capture.stop());
for(size_t i = 0, j = 1; i < expectedSize; ++i, j += 2)
{
ASSERT_EQ(expected[i], output[j]);
}
#endif
}
TEST(ReactorUnitTests, PrintReactorTypes)
{
#ifdef ENABLE_RR_PRINT
FunctionT<void()> function;
{
Bool b(true);
Int i(-1);
Int2 i2(-1, -2);
Int4 i4(-1, -2, -3, -4);
UInt ui(1);
UInt2 ui2(1, 2);
UInt4 ui4(1, 2, 3, 4);
Short s(-1);
Short4 s4(-1, -2, -3, -4);
UShort us(1);
UShort4 us4(1, 2, 3, 4);
Float f(1);
Float4 f4(1, 2, 3, 4);
Long l(i);
Pointer<Int> pi = nullptr;
RValue<Int> rvi = i;
Byte by('a');
Byte4 by4(i4);
RR_WATCH(b);
RR_WATCH(i);
RR_WATCH(i2);
RR_WATCH(i4);
RR_WATCH(ui);
RR_WATCH(ui2);
RR_WATCH(ui4);
RR_WATCH(s);
RR_WATCH(s4);
RR_WATCH(us);
RR_WATCH(us4);
RR_WATCH(f);
RR_WATCH(f4);
RR_WATCH(l);
RR_WATCH(pi);
RR_WATCH(rvi);
RR_WATCH(by);
RR_WATCH(by4);
}
auto routine = function("one");
char piNullptr[64];
snprintf(piNullptr, sizeof(piNullptr), " pi: %p", nullptr);
const char *expected[] = {
" b: true",
" i: -1",
" i2: [-1, -2]",
" i4: [-1, -2, -3, -4]",
" ui: 1",
" ui2: [1, 2]",
" ui4: [1, 2, 3, 4]",
" s: -1",
" s4: [-1, -2, -3, -4]",
" us: 1",
" us4: [1, 2, 3, 4]",
" f: 1.000000",
" f4: [1.000000, 2.000000, 3.000000, 4.000000]",
" l: -1",
piNullptr,
" rvi: -1",
" by: 97",
" by4: [255, 254, 253, 252]",
};
constexpr size_t expectedSize = sizeof(expected) / sizeof(expected[0]);
StdOutCapture capture;
capture.start();
routine();
auto output = split(capture.stop());
for(size_t i = 0, j = 1; i < expectedSize; ++i, j += 2)
{
ASSERT_EQ(expected[i], output[j]);
}
#endif
}
TEST(ReactorUnitTests, Sample) TEST(ReactorUnitTests, Sample)
{ {
FunctionT<int(int *, int)> function; FunctionT<int(int *, int)> function;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "Shader.hpp" #include "Shader.hpp"
#include "Reactor/Reactor.hpp" #include "Reactor/Reactor.hpp"
#include "Reactor/Print.hpp"
#include "Common/Debug.hpp" #include "Common/Debug.hpp"
namespace sw namespace sw
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment