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
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_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(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)
......@@ -543,8 +544,9 @@ else()
endif()
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_ENABLE_PRINT "On")
list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_EMIT_PRINT_LOCATION")
endif()
......@@ -553,6 +555,10 @@ if(REACTOR_EMIT_DEBUG_INFO)
list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_DEBUG_INFO")
endif()
if(REACTOR_ENABLE_PRINT)
list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_PRINT")
endif()
if(REACTOR_VERIFY_LLVM_IR)
list(APPEND SWIFTSHADER_COMPILE_OPTIONS "-DENABLE_RR_LLVM_IR_VERIFICATION")
endif()
......
......@@ -18,6 +18,7 @@
#include "Debug.hpp"
#include "EmulatedReactor.hpp"
#include "LLVMReactorDebugInfo.hpp"
#include "Print.hpp"
#include "Reactor.hpp"
#include "x86.hpp"
......@@ -3874,6 +3875,13 @@ static std::vector<Value *> toDouble(const std::vector<Value *> &vals)
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)
{
return toInt({ v.value }, false);
......@@ -3965,7 +3973,7 @@ void Printv(const char *function, const char *file, int line, const char *fmt, s
if(function != nullptr) { str += "%s "; }
str += fmt;
// Perform subsitution on all '{n}' bracketed indices in the format
// Perform substitution on all '{n}' bracketed indices in the format
// message.
int i = 0;
for(const PrintValue &arg : args)
......
......@@ -18,6 +18,7 @@
# include "LLVMReactor.hpp"
# include "Reactor.hpp"
# include "Print.hpp"
# include "boost/stacktrace.hpp"
......
......@@ -15,10 +15,6 @@
#ifndef 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
# include "Reactor.hpp"
......@@ -147,9 +143,12 @@ public:
PrintValue(double v)
: format(std::to_string(v))
{}
PrintValue(const char *v)
: format(v)
{}
template<typename T>
PrintValue(const T *v)
PrintValue(T *v)
: format(addr(v))
{}
......@@ -226,8 +225,8 @@ struct PrintValue::Ty<std::string>
template<>
struct PrintValue::Ty<Bool>
{
static std::string fmt(const RValue<Bool> &v) { return "%d"; }
static std::vector<Value *> val(const RValue<Bool> &v) { return { v.value }; }
static std::string fmt(const RValue<Bool> &v) { return "%s"; }
static std::vector<Value *> val(const RValue<Bool> &v);
};
template<>
struct PrintValue::Ty<Byte>
......@@ -250,7 +249,7 @@ struct PrintValue::Ty<Int>
template<>
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);
};
template<>
......@@ -268,7 +267,7 @@ struct PrintValue::Ty<UInt>
template<>
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);
};
template<>
......@@ -304,7 +303,7 @@ struct PrintValue::Ty<UShort4>
template<>
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);
};
template<>
......
......@@ -13,6 +13,7 @@
// limitations under the License.
#include "Coroutine.hpp"
#include "Print.hpp"
#include "Reactor.hpp"
#include "gtest/gtest.h"
......@@ -107,6 +108,206 @@ int reference(int *p, int y)
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)
{
FunctionT<int(int *, int)> function;
......
......@@ -17,6 +17,7 @@
#include "Shader.hpp"
#include "Reactor/Reactor.hpp"
#include "Reactor/Print.hpp"
#include "Common/Debug.hpp"
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