Commit c9991d46 by Nicolas Capens Committed by Nicolas Capens

Implement Pragma() for Reactor MemorySanitizer instrumentation

Enabling MemorySanitizer instrumentation for all Reactor routines can have too big of a performance impact. To support selective instrumentation, Pragma(MemorySanitizerInstrumentation, true) can be called to enable it for the next routine that gets created. It must be called before the Function<> constructor. Pragma state is thread local, so Pragma(MemorySanitizerInstrumentation, false) must be called after the routine has been created, to disable it again if instrumentation is not desired for subsequent routines created in this thread. Note that REACTOR_ENABLE_MEMORY_SANITIZER_INSTRUMENTATION=true enables MemorySanitizer instrumentation for Reactor routines even if the pragma state is false. Bug: b/191050320 Change-Id: Ie71aadeae140e85bda31554788288e138df0d08c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/54988 Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent a3726e06
...@@ -206,6 +206,7 @@ cc_defaults { ...@@ -206,6 +206,7 @@ cc_defaults {
"Reactor/LLVMJIT.cpp", "Reactor/LLVMJIT.cpp",
"Reactor/LLVMReactor.cpp", "Reactor/LLVMReactor.cpp",
"Reactor/OptimalIntrinsics.cpp", "Reactor/OptimalIntrinsics.cpp",
"Reactor/Pragma.cpp",
"Reactor/Reactor.cpp", "Reactor/Reactor.cpp",
], ],
......
...@@ -49,6 +49,7 @@ swiftshader_source_set("swiftshader_reactor_base") { ...@@ -49,6 +49,7 @@ swiftshader_source_set("swiftshader_reactor_base") {
"EmulatedIntrinsics.cpp", "EmulatedIntrinsics.cpp",
"ExecutableMemory.cpp", "ExecutableMemory.cpp",
"OptimalIntrinsics.cpp", "OptimalIntrinsics.cpp",
"Pragma.cpp",
"Reactor.cpp", "Reactor.cpp",
] ]
......
...@@ -27,6 +27,9 @@ set(REACTOR_SRC_FILES ...@@ -27,6 +27,9 @@ set(REACTOR_SRC_FILES
Nucleus.hpp Nucleus.hpp
OptimalIntrinsics.cpp OptimalIntrinsics.cpp
OptimalIntrinsics.hpp OptimalIntrinsics.hpp
Pragma.cpp
Pragma.hpp
PragmaInternals.hpp
Print.hpp Print.hpp
Reactor.cpp Reactor.cpp
Reactor.hpp Reactor.hpp
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "Debug.hpp" #include "Debug.hpp"
#include "ExecutableMemory.hpp" #include "ExecutableMemory.hpp"
#include "LLVMAsm.hpp" #include "LLVMAsm.hpp"
#include "PragmaInternals.hpp"
#include "Routine.hpp" #include "Routine.hpp"
// TODO(b/143539525): Eliminate when warning has been fixed. // TODO(b/143539525): Eliminate when warning has been fixed.
...@@ -823,7 +824,8 @@ JITBuilder::JITBuilder(const rr::Config &config) ...@@ -823,7 +824,8 @@ JITBuilder::JITBuilder(const rr::Config &config)
module->setTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE); module->setTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
module->setDataLayout(JITGlobals::get()->getDataLayout()); module->setDataLayout(JITGlobals::get()->getDataLayout());
if(REACTOR_ENABLE_MEMORY_SANITIZER_INSTRUMENTATION) if(REACTOR_ENABLE_MEMORY_SANITIZER_INSTRUMENTATION ||
getPragmaState(MemorySanitizerInstrumentation))
{ {
msanInstrumentation = true; msanInstrumentation = true;
} }
......
// Copyright 2021 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Pragma.hpp"
#include "PragmaInternals.hpp"
#include "Debug.hpp"
namespace rr {
static thread_local bool memorySanitizerInstrumentation = false;
void Pragma(PragmaBooleanOption option, bool enable)
{
switch(option)
{
case MemorySanitizerInstrumentation:
memorySanitizerInstrumentation = enable;
break;
default:
UNSUPPORTED("Unknown pragma %d", int(option));
}
}
bool getPragmaState(PragmaBooleanOption option)
{
switch(option)
{
case MemorySanitizerInstrumentation:
return memorySanitizerInstrumentation;
default:
UNSUPPORTED("Unknown pragma %d", int(option));
return false;
}
}
} // namespace rr
\ No newline at end of file
// Copyright 2021 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef rr_Pragma_hpp
#define rr_Pragma_hpp
namespace rr {
enum PragmaBooleanOption
{
MemorySanitizerInstrumentation,
};
void Pragma(PragmaBooleanOption option, bool enable);
} // namespace rr
#endif // rr_Pragma_hpp
\ No newline at end of file
// Copyright 2021 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef rr_PragmaInternals_hpp
#define rr_PragmaInternals_hpp
#include "Pragma.hpp"
namespace rr {
bool getPragmaState(PragmaBooleanOption option);
} // namespace rr
#endif // rr_Pragma_hpp
\ No newline at end of file
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#define rr_Reactor_hpp #define rr_Reactor_hpp
#include "Nucleus.hpp" #include "Nucleus.hpp"
#include "Pragma.hpp"
#include "Routine.hpp" #include "Routine.hpp"
#include "Traits.hpp" #include "Traits.hpp"
......
...@@ -136,9 +136,16 @@ TEST(ReactorUnitTests, Trampoline) ...@@ -136,9 +136,16 @@ TEST(ReactorUnitTests, Trampoline)
EXPECT_EQ(result, 80); EXPECT_EQ(result, 80);
} }
#if REACTOR_ENABLE_MEMORY_SANITIZER_INSTRUMENTATION
TEST(ReactorUnitTests, Uninitialized) TEST(ReactorUnitTests, Uninitialized)
{ {
#if __has_feature(memory_sanitizer)
// Building the static C++ code with MemorySanitizer enabled does not
// automatically enable MemorySanitizer instrumentation for Reactor
// routines. False positives can also be prevented by unpoisoning all
// memory writes. This Pragma ensures proper instrumentation is enabled.
Pragma(MemorySanitizerInstrumentation, true);
#endif
FunctionT<int()> function; FunctionT<int()> function;
{ {
Int a; Int a;
...@@ -178,8 +185,9 @@ TEST(ReactorUnitTests, Uninitialized) ...@@ -178,8 +185,9 @@ TEST(ReactorUnitTests, Uninitialized)
}, },
"MemorySanitizer: use-of-uninitialized-value"); "MemorySanitizer: use-of-uninitialized-value");
} }
Pragma(MemorySanitizerInstrumentation, false);
} }
#endif
TEST(ReactorUnitTests, Unreachable) TEST(ReactorUnitTests, Unreachable)
{ {
......
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