1*9880d681SAndroid Build Coastguard Worker //===-- RandomNumberGenerator.cpp - Implement RNG class -------------------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file implements deterministic random number generation (RNG). 11*9880d681SAndroid Build Coastguard Worker // The current implementation is NOT cryptographically secure as it uses 12*9880d681SAndroid Build Coastguard Worker // the C++11 <random> facilities. 13*9880d681SAndroid Build Coastguard Worker // 14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/RandomNumberGenerator.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker using namespace llvm; 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "rng" 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker // Tracking BUG: 19665 26*9880d681SAndroid Build Coastguard Worker // http://llvm.org/bugs/show_bug.cgi?id=19665 27*9880d681SAndroid Build Coastguard Worker // 28*9880d681SAndroid Build Coastguard Worker // Do not change to cl::opt<uint64_t> since this silently breaks argument parsing. 29*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned long long> 30*9880d681SAndroid Build Coastguard Worker Seed("rng-seed", cl::value_desc("seed"), 31*9880d681SAndroid Build Coastguard Worker cl::desc("Seed for the random number generator"), cl::init(0)); 32*9880d681SAndroid Build Coastguard Worker RandomNumberGenerator(StringRef Salt)33*9880d681SAndroid Build Coastguard WorkerRandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { 34*9880d681SAndroid Build Coastguard Worker DEBUG( 35*9880d681SAndroid Build Coastguard Worker if (Seed == 0) 36*9880d681SAndroid Build Coastguard Worker dbgs() << "Warning! Using unseeded random number generator.\n" 37*9880d681SAndroid Build Coastguard Worker ); 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker // Combine seed and salts using std::seed_seq. 40*9880d681SAndroid Build Coastguard Worker // Data: Seed-low, Seed-high, Salt 41*9880d681SAndroid Build Coastguard Worker // Note: std::seed_seq can only store 32-bit values, even though we 42*9880d681SAndroid Build Coastguard Worker // are using a 64-bit RNG. This isn't a problem since the Mersenne 43*9880d681SAndroid Build Coastguard Worker // twister constructor copies these correctly into its initial state. 44*9880d681SAndroid Build Coastguard Worker std::vector<uint32_t> Data; 45*9880d681SAndroid Build Coastguard Worker Data.reserve(2 + Salt.size()); 46*9880d681SAndroid Build Coastguard Worker Data.push_back(Seed); 47*9880d681SAndroid Build Coastguard Worker Data.push_back(Seed >> 32); 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker std::copy(Salt.begin(), Salt.end(), Data.end()); 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker std::seed_seq SeedSeq(Data.begin(), Data.end()); 52*9880d681SAndroid Build Coastguard Worker Generator.seed(SeedSeq); 53*9880d681SAndroid Build Coastguard Worker } 54*9880d681SAndroid Build Coastguard Worker operator ()()55*9880d681SAndroid Build Coastguard Workeruint_fast64_t RandomNumberGenerator::operator()() { 56*9880d681SAndroid Build Coastguard Worker return Generator(); 57*9880d681SAndroid Build Coastguard Worker } 58