Order jump tables for deterministic or randomized emission.

BUG=
R=stichnot@chromium.org, jvoung, stichnot

Review URL: https://codereview.chromium.org/1260183008.
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 8bfc5dd..1bcb857 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -878,11 +878,32 @@
   return getConstPool()->ExternRelocatables.getConstantPool();
 }
 
+JumpTableDataList GlobalContext::getJumpTables() {
+  JumpTableDataList JumpTables(*getJumpTableList());
+  if (getFlags().shouldReorderPooledConstants()) {
+  // If reorder-pooled-constants option is set to true, we need to shuffle the
+  // constant pool before emitting it.
+    RandomShuffle(JumpTables.begin(), JumpTables.end(), [this](uint64_t N) {
+      return (uint32_t)getRNG().next(N);
+    });
+  } else {
+    // Make order deterministic by sorting into functions and then ID of the
+    // jump table within that function.
+    std::sort(JumpTables.begin(), JumpTables.end(), [](const JumpTableData &A,
+                                                       const JumpTableData &B) {
+      if (A.getFunctionName() != B.getFunctionName())
+        return A.getFunctionName() < B.getFunctionName();
+      return A.getId() < B.getId();
+    });
+  }
+  return JumpTables;
+}
+
 JumpTableData &GlobalContext::addJumpTable(IceString FuncName, SizeT Id,
                                            SizeT NumTargets) {
-  auto JumpTables = getJumpTables();
-  JumpTables->emplace_back(FuncName, Id, NumTargets);
-  return JumpTables->back();
+  auto JumpTableList = getJumpTableList();
+  JumpTableList->emplace_back(FuncName, Id, NumTargets);
+  return JumpTableList->back();
 }
 
 TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) {
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
index acef4c5..7f27024 100644
--- a/src/IceGlobalContext.h
+++ b/src/IceGlobalContext.h
@@ -212,9 +212,7 @@
   ConstantList getConstantExternSyms();
 
   /// Return a locked pointer to the registered jump tables.
-  LockedPtr<JumpTableDataList> getJumpTables() {
-    return LockedPtr<JumpTableDataList>(&JumpTables, &JumpTablesLock);
-  }
+  JumpTableDataList getJumpTables();
   /// Create a new jump table entry and return a reference to it.
   JumpTableData &addJumpTable(IceString FuncName, SizeT Id, SizeT NumTargets);
 
@@ -467,9 +465,9 @@
   std::unique_ptr<ConstantPool> ConstPool;
 
   ICE_CACHELINE_BOUNDARY;
-  // Managed by getJumpTables()
+  // Managed by getJumpTableList()
   GlobalLockType JumpTablesLock;
-  JumpTableDataList JumpTables;
+  JumpTableDataList JumpTableList;
 
   ICE_CACHELINE_BOUNDARY;
   // Managed by getErrorStatus()
@@ -522,6 +520,9 @@
   LockedPtr<ConstantPool> getConstPool() {
     return LockedPtr<ConstantPool>(ConstPool.get(), &ConstPoolLock);
   }
+  LockedPtr<JumpTableDataList> getJumpTableList() {
+    return LockedPtr<JumpTableDataList>(&JumpTableList, &JumpTablesLock);
+  }
   LockedPtr<CodeStats> getStatsCumulative() {
     return LockedPtr<CodeStats>(&StatsCumulative, &StatsLock);
   }
diff --git a/src/IceSwitchLowering.h b/src/IceSwitchLowering.h
index 34c9373..57c7d3c 100644
--- a/src/IceSwitchLowering.h
+++ b/src/IceSwitchLowering.h
@@ -79,7 +79,6 @@
 /// ELF section once the offsets from the start of the function are known.
 class JumpTableData {
   JumpTableData() = delete;
-  JumpTableData(const JumpTableData &) = delete;
   JumpTableData &operator=(const JumpTableData &) = delete;
 
 public:
@@ -87,7 +86,9 @@
       : FuncName(FuncName), Id(Id) {
     TargetOffsets.reserve(NumTargets);
   }
+  JumpTableData(const JumpTableData &) = default;
   JumpTableData(JumpTableData &&) = default;
+  JumpTableData &operator=(JumpTableData &&) = default;
 
   void pushTarget(intptr_t Offset) { TargetOffsets.emplace_back(Offset); }
 
@@ -98,8 +99,8 @@
   }
 
 private:
-  const IceString FuncName;
-  const SizeT Id;
+  IceString FuncName;
+  SizeT Id;
   std::vector<intptr_t> TargetOffsets;
 };
 
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index e8e89dd..a42e122 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -243,8 +243,8 @@
   switch (Ctx->getFlags().getOutFileType()) {
   case FT_Elf: {
     ELFObjectWriter *Writer = Ctx->getObjectWriter();
-    for (const JumpTableData &JumpTable : *Ctx->getJumpTables())
-      Writer->writeJumpTable(JumpTable, llvm::ELF::R_386_32);
+    for (const JumpTableData &JT : Ctx->getJumpTables())
+      Writer->writeJumpTable(JT, llvm::ELF::R_386_32);
   } break;
   case FT_Asm:
     // Already emitted from Cfg
@@ -253,7 +253,7 @@
     if (!BuildDefs::dump())
       return;
     Ostream &Str = Ctx->getStrEmit();
-    for (const JumpTableData &JT : *Ctx->getJumpTables()) {
+    for (const JumpTableData &JT : Ctx->getJumpTables()) {
       Str << "\t.section\t.rodata." << JT.getFunctionName()
           << "$jumptable,\"a\",@progbits\n";
       Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
index ed586a3..1fcf0b9 100644
--- a/src/IceTargetLoweringX8664.cpp
+++ b/src/IceTargetLoweringX8664.cpp
@@ -240,9 +240,9 @@
   switch (Ctx->getFlags().getOutFileType()) {
   case FT_Elf: {
     ELFObjectWriter *Writer = Ctx->getObjectWriter();
-    for (const JumpTableData &JumpTable : *Ctx->getJumpTables())
+    for (const JumpTableData &JT : Ctx->getJumpTables())
       // TODO(jpp): not 386.
-      Writer->writeJumpTable(JumpTable, llvm::ELF::R_386_32);
+      Writer->writeJumpTable(JT, llvm::ELF::R_386_32);
   } break;
   case FT_Asm:
     // Already emitted from Cfg
@@ -251,7 +251,7 @@
     if (!BuildDefs::dump())
       return;
     Ostream &Str = Ctx->getStrEmit();
-    for (const JumpTableData &JT : *Ctx->getJumpTables()) {
+    for (const JumpTableData &JT : Ctx->getJumpTables()) {
       Str << "\t.section\t.rodata." << JT.getFunctionName()
           << "$jumptable,\"a\",@progbits\n";
       Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";