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