Home | History | Annotate | Download | only in src
      1 //===- subzero/src/IceRNG.cpp - PRNG implementation -----------------------===//
      2 //
      3 //                        The Subzero Code Generator
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief Implements the random number generator.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "IceRNG.h"
     16 
     17 #include <climits>
     18 #include <ctime>
     19 
     20 namespace Ice {
     21 
     22 namespace {
     23 constexpr unsigned MAX = 2147483647;
     24 } // end of anonymous namespace
     25 
     26 // TODO(wala,stichnot): Switch to RNG implementation from LLVM or C++11.
     27 //
     28 // TODO(wala,stichnot): Make it possible to replay the RNG sequence in a
     29 // subsequent run, for reproducing a bug. Print the seed in a comment in the
     30 // asm output. Embed the seed in the binary via metadata that an attacker can't
     31 // introspect.
     32 RandomNumberGenerator::RandomNumberGenerator(uint64_t Seed, llvm::StringRef)
     33     : State(Seed) {}
     34 
     35 RandomNumberGenerator::RandomNumberGenerator(
     36     uint64_t Seed, RandomizationPassesEnum RandomizationPassID, uint64_t Salt) {
     37   constexpr unsigned NumBitsGlobalSeed = CHAR_BIT * sizeof(State);
     38   constexpr unsigned NumBitsPassID = 4;
     39   constexpr unsigned NumBitsSalt = 12;
     40   static_assert(RPE_num < (1 << NumBitsPassID), "NumBitsPassID too small");
     41   State = Seed ^ ((uint64_t)RandomizationPassID
     42                   << (NumBitsGlobalSeed - NumBitsPassID)) ^
     43           (Salt << (NumBitsGlobalSeed - NumBitsPassID - NumBitsSalt));
     44 }
     45 uint64_t RandomNumberGenerator::next(uint64_t Max) {
     46   // Lewis, Goodman, and Miller (1969)
     47   State = (16807 * State) % MAX;
     48   return State % Max;
     49 }
     50 
     51 bool RandomNumberGeneratorWrapper::getTrueWithProbability(float Probability) {
     52   return RNG.next(MAX) < Probability * MAX;
     53 }
     54 
     55 } // end of namespace Ice
     56