From: Mehdi Amini Date: Tue, 11 Oct 2016 07:13:01 +0000 (+0000) Subject: Make RandomNumberGenerator compatible with X-Git-Tag: android-x86-7.1-r4~25969 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=6a59bc7c7d3ab242fd7a93e2a541a38489c12166;p=android-x86%2Fexternal-llvm.git Make RandomNumberGenerator compatible with LLVM's RandomNumberGenerator wasn't compatible with the random distribution from . Fixes PR25105 Patch by: Serge Guelton Differential Revision: https://reviews.llvm.org/D25443 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283854 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Support/RandomNumberGenerator.h b/include/llvm/Support/RandomNumberGenerator.h index 31ae2759e3f..12501326e5e 100644 --- a/include/llvm/Support/RandomNumberGenerator.h +++ b/include/llvm/Support/RandomNumberGenerator.h @@ -31,9 +31,20 @@ class StringRef; /// Module::createRNG to create a new RNG instance for use with that /// module. class RandomNumberGenerator { + + // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000 + // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine + // This RNG is deterministically portable across C++11 + // implementations. + using generator_type = std::mt19937_64; + public: + using result_type = generator_type::result_type; + /// Returns a random number in the range [0, Max). - uint_fast64_t operator()(); + result_type operator()(); + static constexpr result_type min() { return generator_type::min(); } + static constexpr result_type max() { return generator_type::max(); } private: /// Seeds and salts the underlying RNG engine. @@ -42,11 +53,7 @@ private: /// Module::createRNG to create a new RNG salted with the Module ID. RandomNumberGenerator(StringRef Salt); - // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000 - // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine - // This RNG is deterministically portable across C++11 - // implementations. - std::mt19937_64 Generator; + generator_type Generator; // Noncopyable. RandomNumberGenerator(const RandomNumberGenerator &other) = delete; diff --git a/lib/Support/RandomNumberGenerator.cpp b/lib/Support/RandomNumberGenerator.cpp index 087c6710dff..d340764f32a 100644 --- a/lib/Support/RandomNumberGenerator.cpp +++ b/lib/Support/RandomNumberGenerator.cpp @@ -57,7 +57,7 @@ RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { Generator.seed(SeedSeq); } -uint_fast64_t RandomNumberGenerator::operator()() { +RandomNumberGenerator::result_type RandomNumberGenerator::operator()() { return Generator(); } diff --git a/unittests/IR/ModuleTest.cpp b/unittests/IR/ModuleTest.cpp index c5f0bcb08f3..043ea04a0c1 100644 --- a/unittests/IR/ModuleTest.cpp +++ b/unittests/IR/ModuleTest.cpp @@ -9,8 +9,11 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Module.h" +#include "llvm/Support/RandomNumberGenerator.h" #include "gtest/gtest.h" +#include + using namespace llvm; namespace { @@ -45,4 +48,28 @@ TEST(ModuleTest, sortGlobalsByName) { } } +TEST(ModuleTest, randomNumberGenerator) { + LLVMContext Context; + static char ID; + struct DummyPass : ModulePass { + DummyPass() : ModulePass(ID) {} + bool runOnModule(Module &) { return true; } + } DP; + + Module M("R", Context); + + std::uniform_int_distribution dist; + constexpr std::size_t NBCheck = 10; + + std::array RandomStreams[2]; + for (auto &RandomStream : RandomStreams) { + std::unique_ptr RNG{M.createRNG(&DP)}; + std::generate(RandomStream.begin(), RandomStream.end(), + [&]() { return dist(*RNG); }); + } + + EXPECT_TRUE(std::equal(RandomStreams[0].begin(), RandomStreams[0].end(), + RandomStreams[1].begin())); +} + } // end namespace