<div dir="ltr">This is broken, reverting and letting Julian investigate.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jun 17, 2014 at 11:23 PM, JF Bastien <span dir="ltr"><<a href="mailto:jfb@google.com" target="_blank">jfb@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jfb<br>
Date: Wed Jun 18 01:23:25 2014<br>
New Revision: 211145<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=211145&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=211145&view=rev</a><br>
Log:<br>
Random Number Generator (llvm)<br>
<br>
Summary:<br>
Provides an abstraction for a random number generator (RNG) that produces a stream of pseudo-random numbers.<br>
The current implementation uses C++11 facilities and is therefore not cryptographically secure.<br>
<br>
The RNG is salted with the text of the current command line invocation.<br>
In addition, a user may specify a seed (reproducible builds).<br>
<br>
In clang, the seed can be set via<br>
  -frandom-seed=X<br>
In the back end, the seed can be set via<br>
  -rng-seed=X<br>
<br>
This is the llvm part of the patch.<br>
clang part: D3391<br>
<br>
Reviewers: ahomescu, rinon, nicholas, jfb<br>
<br>
Reviewed By: jfb<br>
<br>
Subscribers: jfb, perl<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D3390" target="_blank">http://reviews.llvm.org/D3390</a><br>
<br>
Added:<br>
    llvm/trunk/include/llvm/Support/RandomNumberGenerator.h   (with props)<br>
    llvm/trunk/lib/Support/RandomNumberGenerator.cpp   (with props)<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/Module.h<br>
    llvm/trunk/lib/IR/Module.cpp<br>
    llvm/trunk/lib/Support/CMakeLists.txt<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Module.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=211145&r1=211144&r2=211145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=211145&r1=211144&r2=211145&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Module.h (original)<br>
+++ llvm/trunk/include/llvm/IR/Module.h Wed Jun 18 01:23:25 2014<br>
@@ -29,6 +29,7 @@ namespace llvm {<br>
 class FunctionType;<br>
 class GVMaterializer;<br>
 class LLVMContext;<br>
+class RandomNumberGenerator;<br>
 class StructType;<br>
 template<typename T> struct DenseMapInfo;<br>
 template<typename KeyT, typename ValueT, typename KeyInfoT> class DenseMap;<br>
@@ -201,6 +202,8 @@ private:<br>
   std::string ModuleID;           ///< Human readable identifier for the module<br>
   std::string TargetTriple;       ///< Platform target triple Module compiled on<br>
   void *NamedMDSymTab;            ///< NamedMDNode names.<br>
+  // Allow lazy initialization in const method.<br>
+  mutable RandomNumberGenerator *RNG; ///< The random number generator for this module.<br>
<br>
   // We need to keep the string because the C API expects us to own the string<br>
   // representation.<br>
@@ -249,6 +252,11 @@ public:<br>
   /// @returns a string containing the module-scope inline assembly blocks.<br>
   const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; }<br>
<br>
+  /// Get the RandomNumberGenerator for this module. The RNG can be<br>
+  /// seeded via -rng-seed=<uint64> and is salted with the ModuleID.<br>
+  /// The returned RNG should not be shared across threads.<br>
+  RandomNumberGenerator &getRNG() const;<br>
+<br>
 /// @}<br>
 /// @name Module Level Mutators<br>
 /// @{<br>
<br>
Added: llvm/trunk/include/llvm/Support/RandomNumberGenerator.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/RandomNumberGenerator.h?rev=211145&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/RandomNumberGenerator.h?rev=211145&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/Support/RandomNumberGenerator.h (added)<br>
+++ llvm/trunk/include/llvm/Support/RandomNumberGenerator.h Wed Jun 18 01:23:25 2014<br>
@@ -0,0 +1,53 @@<br>
+//==- llvm/Support/RandomNumberGenerator.h - RNG for diversity ---*- C++ -*-==//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines an abstraction for random number generation (RNG).<br>
+// Note that the current implementation is not cryptographically secure<br>
+// as it uses the C++11 <random> facilities.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_<br>
+#define LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_<br>
+<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include <random><br>
+<br>
+namespace llvm {<br>
+<br>
+/// A random number generator.<br>
+/// Instances of this class should not be shared across threads.<br>
+class RandomNumberGenerator {<br>
+public:<br>
+  /// Seeds and salts the underlying RNG engine. The salt of type StringRef<br>
+  /// is passed into the constructor. The seed can be set on the command<br>
+  /// line via -rng-seed=<uint64>.<br>
+  /// The reason for the salt is to ensure different random streams even if<br>
+  /// the same seed is used for multiple invocations of the compiler.<br>
+  /// A good salt value should add additional entropy and be constant across<br>
+  /// different machines (i.e., no paths) to allow for reproducible builds.<br>
+  /// An instance of this class can be retrieved from the current Module.<br>
+  /// \see Module::getRNG<br>
+  RandomNumberGenerator(StringRef Salt);<br>
+<br>
+  /// Returns a random number in the range [0, Max).<br>
+  uint64_t next(uint64_t Max);<br>
+<br>
+private:<br>
+  // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000<br>
+  // <a href="http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine" target="_blank">http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine</a><br>
+  std::mt19937_64 Generator;<br>
+<br>
+  // Noncopyable.<br>
+  RandomNumberGenerator(const RandomNumberGenerator &other) = delete;<br>
+  RandomNumberGenerator &operator=(const RandomNumberGenerator &other) = delete;<br>
+};<br>
+}<br>
+<br>
+#endif<br>
<br>
Propchange: llvm/trunk/include/llvm/Support/RandomNumberGenerator.h<br>
------------------------------------------------------------------------------<br>
    svn:eol-style = LF<br>
<br>
Modified: llvm/trunk/lib/IR/Module.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Module.cpp?rev=211145&r1=211144&r2=211145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Module.cpp?rev=211145&r1=211144&r2=211145&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/IR/Module.cpp (original)<br>
+++ llvm/trunk/lib/IR/Module.cpp Wed Jun 18 01:23:25 2014<br>
@@ -24,6 +24,8 @@<br>
 #include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/IR/LeakDetector.h"<br>
 #include "llvm/Support/Dwarf.h"<br>
+#include "llvm/Support/Path.h"<br>
+#include "llvm/Support/RandomNumberGenerator.h"<br>
 #include <algorithm><br>
 #include <cstdarg><br>
 #include <cstdlib><br>
@@ -44,7 +46,7 @@ template class llvm::SymbolTableListTrai<br>
 //<br>
<br>
 Module::Module(StringRef MID, LLVMContext &C)<br>
-    : Context(C), Materializer(), ModuleID(MID), DL("") {<br>
+    : Context(C), Materializer(), ModuleID(MID), RNG(nullptr), DL("") {<br>
   ValSymTab = new ValueSymbolTable();<br>
   NamedMDSymTab = new StringMap<NamedMDNode *>();<br>
   Context.addModule(this);<br>
@@ -59,6 +61,7 @@ Module::~Module() {<br>
   NamedMDList.clear();<br>
   delete ValSymTab;<br>
   delete static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab);<br>
+  delete RNG;<br>
 }<br>
<br>
 /// getNamedValue - Return the first global value in the module with<br>
@@ -355,6 +358,16 @@ const DataLayout *Module::getDataLayout(<br>
   return &DL;<br>
 }<br>
<br>
+// We want reproducible builds, but ModuleID may be a full path so we just use<br>
+// the filename to salt the RNG (although it is not guaranteed to be unique).<br>
+RandomNumberGenerator &Module::getRNG() const {<br>
+  if (RNG == nullptr) {<br>
+    StringRef Salt = sys::path::filename(ModuleID);<br>
+    RNG = new RandomNumberGenerator(Salt);<br>
+  }<br>
+  return *RNG;<br>
+}<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 // Methods to control the materialization of GlobalValues in the Module.<br>
 //<br>
<br>
Modified: llvm/trunk/lib/Support/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=211145&r1=211144&r2=211145&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=211145&r1=211144&r2=211145&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Support/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/Support/CMakeLists.txt Wed Jun 18 01:23:25 2014<br>
@@ -41,6 +41,7 @@ add_llvm_library(LLVMSupport<br>
   MD5.cpp<br>
   PluginLoader.cpp<br>
   PrettyStackTrace.cpp<br>
+  RandomNumberGenerator.cpp<br>
   Regex.cpp<br>
   SmallPtrSet.cpp<br>
   SmallVector.cpp<br>
<br>
Added: llvm/trunk/lib/Support/RandomNumberGenerator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/RandomNumberGenerator.cpp?rev=211145&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/RandomNumberGenerator.cpp?rev=211145&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Support/RandomNumberGenerator.cpp (added)<br>
+++ llvm/trunk/lib/Support/RandomNumberGenerator.cpp Wed Jun 18 01:23:25 2014<br>
@@ -0,0 +1,52 @@<br>
+//===-- RandomNumberGenerator.cpp - Implement RNG class -------------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file implements random number generation (RNG).<br>
+// The current implementation is NOT cryptographically secure as it uses<br>
+// the C++11 <random> facilities.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#define DEBUG_TYPE "rng"<br>
+#include "llvm/Support/RandomNumberGenerator.h"<br>
+#include "llvm/Support/CommandLine.h"<br>
+#include "llvm/Support/Debug.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+// Tracking BUG: 19665<br>
+// <a href="http://llvm.org/bugs/show_bug.cgi?id=19665" target="_blank">http://llvm.org/bugs/show_bug.cgi?id=19665</a><br>
+//<br>
+// Do not change to cl::opt<uint64_t> since this silently breaks argument parsing.<br>
+static cl::opt<unsigned long long><br>
+Seed("rng-seed", cl::value_desc("seed"),<br>
+     cl::desc("Seed for the random number generator"), cl::init(0));<br>
+<br>
+RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) {<br>
+  DEBUG(<br>
+    if (Seed == 0)<br>
+      errs() << "Warning! Using unseeded random number generator.\n"<br>
+  );<br>
+<br>
+  // Combine seed and salt using std::seed_seq.<br>
+  // Entropy: Seed-low, Seed-high, Salt...<br>
+  size_t Size = Salt.size() + 2;<br>
+  uint32_t Data[Size];<br>
+  Data[0] = Seed;<br>
+  Data[1] = Seed >> 32;<br>
+  std::copy_n(Salt.begin(), Salt.size(), Data + 2);<br>
+<br>
+  std::seed_seq SeedSeq(Data, Data + Size);<br>
+  Generator.seed(SeedSeq);<br>
+}<br>
+<br>
+uint64_t RandomNumberGenerator::next(uint64_t Max) {<br>
+  std::uniform_int_distribution<uint64_t> distribution(0, Max - 1);<br>
+  return distribution(Generator);<br>
+}<br>
<br>
Propchange: llvm/trunk/lib/Support/RandomNumberGenerator.cpp<br>
------------------------------------------------------------------------------<br>
    svn:eol-style = LF<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>