Make rr::Print output to debugger and be stubbed

This change now also makes it so that when rr::Print is enabled, it will
output to stdout and to the debugger, if available. For now, that means
it calls OutputDebugString on Windows. This is useful when it is
difficult to capture stdout (e.g. debugging Chrome).

Also, you can now modify Reactor.cpp and uncomment
`#define RR_PRINT_OUTPUT_TYPE_STUB` to stub out the function itself.
This is useful in combination with ENABLE_RR_EMIT_PRINT_LOCATION in that
debugging the code-gen assembly allows you to inspect the string
argument to rr::DebugPrintf and see exactly where you are in Reactor
code without paying the performance cost of actually printing.

Bug: b/158678105
Change-Id: Ie1bd85888405e189200c0e5f8f3449551327e0ab
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/45669
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Reactor/LLVMJIT.cpp b/src/Reactor/LLVMJIT.cpp
index 68153a7..e4c8128 100644
--- a/src/Reactor/LLVMJIT.cpp
+++ b/src/Reactor/LLVMJIT.cpp
@@ -434,6 +434,9 @@
 
 		Resolver()
 		{
+#ifdef ENABLE_RR_PRINT
+			functions.emplace("rr::DebugPrintf", reinterpret_cast<void *>(rr::DebugPrintf));
+#endif
 			functions.emplace("nop", reinterpret_cast<void *>(F::nop));
 			functions.emplace("floorf", reinterpret_cast<void *>(floorf));
 			functions.emplace("nearbyintf", reinterpret_cast<void *>(nearbyintf));
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index eacba83..fca41e4 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -3985,7 +3985,7 @@
 	auto i32Ty = ::llvm::Type::getInt32Ty(jit->context);
 	auto i8PtrTy = ::llvm::Type::getInt8PtrTy(jit->context);
 	auto funcTy = ::llvm::FunctionType::get(i32Ty, { i8PtrTy }, true);
-	auto func = jit->module->getOrInsertFunction("printf", funcTy);
+	auto func = jit->module->getOrInsertFunction("rr::DebugPrintf", funcTy);
 	jit->builder->CreateCall(func, V(vals));
 }
 #endif  // ENABLE_RR_PRINT
diff --git a/src/Reactor/Reactor.cpp b/src/Reactor/Reactor.cpp
index db8654e..d09ddfe 100644
--- a/src/Reactor/Reactor.cpp
+++ b/src/Reactor/Reactor.cpp
@@ -20,6 +20,13 @@
 #include <algorithm>
 #include <cmath>
 
+#if defined(_WIN32)
+#	ifndef WIN32_LEAN_AND_MEAN
+#		define WIN32_LEAN_AND_MEAN
+#	endif
+#	include <windows.h>
+#endif
+
 namespace rr {
 
 const Config::Edit Config::Edit::None = {};
@@ -4568,6 +4575,35 @@
 	// This call is implemented by each backend
 	VPrintf(vals);
 }
+
+// This is the function that is called by VPrintf from the backends
+int DebugPrintf(const char *format, ...)
+{
+	// Uncomment this to make it so that we do not print, but the call to this function is emitted.
+	// Useful when debugging emitted code to see the Reactor source location.
+	//#	define RR_PRINT_OUTPUT_TYPE_STUB
+
+#	if defined(RR_PRINT_OUTPUT_TYPE_STUB)
+	return 0;
+#	else
+
+	int result;
+	va_list args;
+
+	va_start(args, format);
+	char buffer[2048];
+	result = vsprintf(buffer, format, args);
+	va_end(args);
+
+	std::fputs(buffer, stdout);
+#		if defined(_WIN32)
+	OutputDebugString(buffer);
+#		endif
+
+	return result;
+#	endif
+}
+
 #endif  // ENABLE_RR_PRINT
 
 }  // namespace rr
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 825480b..e8d053b 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -48,6 +48,12 @@
 #	define RR_DEBUG_INFO_FLUSH()
 #endif  // ENABLE_RR_DEBUG_INFO
 
+#ifdef ENABLE_RR_PRINT
+namespace rr {
+int DebugPrintf(const char *format, ...);
+}
+#endif
+
 namespace rr {
 
 std::string BackendName();
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 12f115f..9b87a66 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -849,7 +849,7 @@
 #ifdef ENABLE_RR_PRINT
 void VPrintf(const std::vector<Value *> &vals)
 {
-	sz::Call(::function, ::basicBlock, Ice::IceType_i32, reinterpret_cast<const void *>(::printf), V(vals), true);
+	sz::Call(::function, ::basicBlock, Ice::IceType_i32, reinterpret_cast<const void *>(rr::DebugPrintf), V(vals), true);
 }
 #endif  // ENABLE_RR_PRINT