<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>