Allow ability to name unnamed global addresses in Subzero.

This is a workaround for issue that Subzero currently assumes all
global addresses have a name, but finalized pexe files leave most
global addresses unnamed.

It does this by allowing two optional command-line flag name prefixes
that are used to generate names for unnamed global addresses.

BUG= None
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/567703003
diff --git a/src/IceClFlags.h b/src/IceClFlags.h
index 5cf534c..858b7c1 100644
--- a/src/IceClFlags.h
+++ b/src/IceClFlags.h
@@ -14,20 +14,26 @@
 #ifndef SUBZERO_SRC_ICECLFLAGS_H
 #define SUBZERO_SRC_ICECLFLAGS_H
 
+#include "IceTypes.def"
+
 namespace Ice {
 
+// TODO(stichnot) Move more command line flags into ClFlags.
 class ClFlags {
 public:
   ClFlags()
       : DisableInternal(false), SubzeroTimingEnabled(false),
         DisableTranslation(false), DisableGlobals(false),
-        FunctionSections(false), UseSandboxing(false) {}
+        FunctionSections(false), UseSandboxing(false), DefaultGlobalPrefix(""),
+        DefaultFunctionPrefix("") {}
   bool DisableInternal;
   bool SubzeroTimingEnabled;
   bool DisableTranslation;
   bool DisableGlobals;
   bool FunctionSections;
   bool UseSandboxing;
+  IceString DefaultGlobalPrefix;
+  IceString DefaultFunctionPrefix;
 };
 
 } // end of namespace Ice
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp
index ca73a8b..271d25c 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -608,6 +608,7 @@
 namespace Ice {
 
 void Converter::convertToIce() {
+  nameUnnamedGlobalAddresses(Mod);
   if (!Ctx->getFlags().DisableGlobals)
     convertGlobals();
   convertFunctions();
diff --git a/src/IceTranslator.cpp b/src/IceTranslator.cpp
index 59403d2..05332b4 100644
--- a/src/IceTranslator.cpp
+++ b/src/IceTranslator.cpp
@@ -16,7 +16,9 @@
 
 #include "IceCfg.h"
 #include "IceClFlags.h"
+#include "IceDefs.h"
 #include "IceTargetLowering.h"
+#include "llvm/IR/Module.h"
 
 #include <iostream>
 
@@ -24,14 +26,58 @@
 
 Translator::~Translator() {}
 
-void Translator::translateFcn(Ice::Cfg *Fcn) {
+namespace {
+void setValueName(llvm::Value *V, const char *Kind, const IceString &Prefix,
+                  uint32_t &NameIndex, Ostream &errs) {
+  if (V->hasName()) {
+    const std::string &Name(V->getName());
+    if (Name.find(Prefix) == 0) {
+      errs << "Warning: Default " << Kind << " prefix '" << Prefix
+           << "' conflicts with name '" << Name << "'.\n";
+    }
+    return;
+  }
+  if (NameIndex == 0) {
+    V->setName(Prefix);
+    ++NameIndex;
+    return;
+  }
+  std::string Buffer;
+  llvm::raw_string_ostream StrBuf(Buffer);
+  StrBuf << Prefix << NameIndex;
+  V->setName(StrBuf.str());
+  ++NameIndex;
+}
+} // end of anonymous namespace
+
+void Translator::nameUnnamedGlobalAddresses(llvm::Module *Mod) {
+  const IceString &GlobalPrefix = Flags.DefaultGlobalPrefix;
+  Ostream &errs = Ctx->getStrDump();
+  if (!GlobalPrefix.empty()) {
+    uint32_t NameIndex = 0;
+    for (llvm::Module::global_iterator I = Mod->global_begin(),
+                                       E = Mod->global_end();
+         I != E; ++I) {
+      setValueName(I, "global", GlobalPrefix, NameIndex, errs);
+    }
+  }
+  const IceString &FunctionPrefix = Flags.DefaultFunctionPrefix;
+  if (FunctionPrefix.empty())
+    return;
+  uint32_t NameIndex = 0;
+  for (llvm::Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) {
+    setValueName(I, "function", FunctionPrefix, NameIndex, errs);
+  }
+}
+
+void Translator::translateFcn(Cfg *Fcn) {
   Func.reset(Fcn);
   if (Ctx->getFlags().DisableInternal)
     Func->setInternal(false);
   if (Ctx->getFlags().DisableTranslation) {
     Func->dump();
   } else {
-    Ice::Timer TTranslate;
+    Timer TTranslate;
     Func->translate();
     if (Ctx->getFlags().SubzeroTimingEnabled) {
       std::cerr << "[Subzero timing] Translate function "
@@ -43,7 +89,7 @@
       ErrorStatus = true;
     }
 
-    Ice::Timer TEmit;
+    Timer TEmit;
     Func->emit();
     if (Ctx->getFlags().SubzeroTimingEnabled) {
       std::cerr << "[Subzero timing] Emit function " << Func->getFunctionName()
diff --git a/src/IceTranslator.h b/src/IceTranslator.h
index ec5c032..2ca6d42 100644
--- a/src/IceTranslator.h
+++ b/src/IceTranslator.h
@@ -17,6 +17,10 @@
 
 #include "llvm/ADT/OwningPtr.h"
 
+namespace llvm {
+class Module;
+}
+
 namespace Ice {
 
 class ClFlags;
@@ -47,6 +51,11 @@
   /// Emits the constant pool.
   void emitConstants();
 
+  // Walks module and generates names for unnamed globals and
+  // functions using prefix getFlags().DefaultGlobalPrefix, if the
+  // prefix is non-empty.
+  void nameUnnamedGlobalAddresses(llvm::Module *Mod);
+
 protected:
   GlobalContext *Ctx;
   const ClFlags &Flags;
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index bb04d61..fcebeac 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -1887,11 +1887,14 @@
 class ModuleParser : public BlockParserBaseClass {
 public:
   ModuleParser(unsigned BlockID, TopLevelParser *Context)
-      : BlockParserBaseClass(BlockID, Context) {}
+      : BlockParserBaseClass(BlockID, Context), FoundFirstFunctionBlock(false) {
+  }
 
   virtual ~ModuleParser() LLVM_OVERRIDE {}
 
-protected:
+private:
+  // True if we have parsed a function block.
+  bool FoundFirstFunctionBlock;
   virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
 
   virtual void ProcessRecord() LLVM_OVERRIDE;
@@ -1950,6 +1953,10 @@
     return Parser.ParseThisBlock();
   }
   case naclbitc::FUNCTION_BLOCK_ID: {
+    if (!FoundFirstFunctionBlock) {
+      getTranslator().nameUnnamedGlobalAddresses(Context->getModule());
+      FoundFirstFunctionBlock = true;
+    }
     FunctionParser Parser(BlockID, this);
     return Parser.ParseThisBlock();
   }
diff --git a/src/llvm2ice.cpp b/src/llvm2ice.cpp
index 986ff76..ce700b7 100644
--- a/src/llvm2ice.cpp
+++ b/src/llvm2ice.cpp
@@ -109,6 +109,18 @@
                clEnumValEnd),
     cl::init(LLVMFormat));
 
+static cl::opt<std::string>
+    DefaultGlobalPrefix("default-global-prefix",
+                        cl::desc("Define default global prefix for naming "
+                                 "unnamed globals"),
+                        cl::init("Global"));
+
+static cl::opt<std::string>
+    DefaultFunctionPrefix("default-function-prefix",
+                          cl::desc("Define default function prefix for naming "
+                                   "unnamed functions"),
+                          cl::init("Function"));
+
 static cl::opt<bool>
 BuildOnRead("build-on-read",
             cl::desc("Build ICE instructions when reading bitcode"),
@@ -143,6 +155,8 @@
   Flags.DisableGlobals = DisableGlobals;
   Flags.FunctionSections = FunctionSections;
   Flags.UseSandboxing = UseSandboxing;
+  Flags.DefaultGlobalPrefix = DefaultGlobalPrefix;
+  Flags.DefaultFunctionPrefix = DefaultFunctionPrefix;
 
   Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix,
                          Flags);