Subzero: Embed the revision string into translated output.
Modify the Makefiles to pass in the current git hash, which is embedded into the translated output. As a side effect, it is also embedded into the Subzero translator binary. This is useful for two reasons:
1. The PNaCl component update process is somewhat manual, making it tricky long after the fact to know exactly which revision was pushed, e.g. when trying to reproduce a bug or crash.
2. A translated binary can be inspected to make sure Chrome used the expected revision of Subzero. (And also to verify that pnacl-sz was used rather than pnacl-llc.)
The revision string is suppressed for lit tests, because a number of tests seem overly strict about global initializer expectations.
BUG= none
R=jpp@chromium.org
Review URL: https://codereview.chromium.org/2218363002 .
diff --git a/Makefile b/Makefile
index 52bfba3..e49eec3 100644
--- a/Makefile
+++ b/Makefile
@@ -31,3 +31,4 @@
endif
CPP.Defines += -DPNACL_LLVM
+CPP.Defines += -DSUBZERO_REVISION=$(shell git rev-parse HEAD)
diff --git a/Makefile.standalone b/Makefile.standalone
index a75ea94..56fd8a4 100644
--- a/Makefile.standalone
+++ b/Makefile.standalone
@@ -111,6 +111,7 @@
endif
BASE_CXX_DEFINES += -DPNACL_LLVM
+BASE_CXX_DEFINES += -DSUBZERO_REVISION=$(shell git rev-parse HEAD)
CXX_DEFINES := $(BASE_CXX_DEFINES) -DPNACL_BROWSER_TRANSLATOR=0
@@ -320,6 +321,7 @@
IceOperand.cpp \
IceRangeSpec.cpp \
IceRegAlloc.cpp \
+ IceRevision.cpp \
IceRNG.cpp \
IceSwitchLowering.cpp \
IceThreading.cpp \
diff --git a/pydir/crosstest.py b/pydir/crosstest.py
index 3727d5c..2ca673e 100755
--- a/pydir/crosstest.py
+++ b/pydir/crosstest.py
@@ -165,9 +165,11 @@
# definitions.) This approach should be OK because cross tests are
# currently the only situation where multiple translated files are
# linked into the executable, but when PNaCl supports shared nexe
- # libraries, this would need to change.
+ # libraries, this would need to change. (Note: the same issue applies
+ # to the __Sz_revision symbol.)
shellcmd(['{bin}/{objcopy}'.format(bin=bindir, objcopy=GetObjcopyCmd()),
'--weaken-symbol=__Sz_block_profile_info',
+ '--weaken-symbol=__Sz_revision',
'--strip-symbol=nacl_tp_tdb_offset',
'--strip-symbol=nacl_tp_tls_offset',
obj_sz])
@@ -181,7 +183,6 @@
'-o=' + obj_llc,
bitcode] + llc_flags)
shellcmd(['{bin}/{objcopy}'.format(bin=bindir, objcopy=GetObjcopyCmd()),
- '--weaken-symbol=__Sz_block_profile_info',
'--strip-symbol=nacl_tp_tdb_offset',
'--strip-symbol=nacl_tp_tls_offset',
obj_llc])
diff --git a/pydir/run-pnacl-sz.py b/pydir/run-pnacl-sz.py
index dc549e8..580d227 100755
--- a/pydir/run-pnacl-sz.py
+++ b/pydir/run-pnacl-sz.py
@@ -164,6 +164,7 @@
else:
cmd += ['--build-on-read=1']
cmd += ['--filetype=' + args.filetype]
+ cmd += ['--emit-revision=0']
script_name = os.path.basename(sys.argv[0])
for _, arg in enumerate(args.args):
# Redirecting the output file needs to be done through the script
diff --git a/src/IceClFlags.def b/src/IceClFlags.def
index f13afbe..bb9a181 100644
--- a/src/IceClFlags.def
+++ b/src/IceClFlags.def
@@ -153,6 +153,9 @@
clEnumValN(Ice::LCSE_EnabledNoSSA, "no-ssa", "no-assume-ssa"), \
clEnumValEnd)) \
\
+ X(EmitRevision, bool, dev_opt_flag, "emit-revision", \
+ cl::desc("Emit Subzero revision string into the output"), cl::init(true)) \
+ \
X(EnablePhiEdgeSplit, bool, dev_opt_flag, "phi-edge-split", \
cl::desc("Enable edge splitting for Phi lowering"), cl::init(true)) \
\
diff --git a/src/IceCompileServer.cpp b/src/IceCompileServer.cpp
index 5ace25c..a021f8f 100644
--- a/src/IceCompileServer.cpp
+++ b/src/IceCompileServer.cpp
@@ -18,6 +18,7 @@
#include "IceClFlags.h"
#include "IceELFStreamer.h"
#include "IceGlobalContext.h"
+#include "IceRevision.h"
#include "LinuxMallocProfiling.h"
#ifdef __clang__
@@ -163,6 +164,7 @@
const auto &A = ConditionalBuildAttributes[i];
Str << Prefix[A.FlagValue] << "_" << A.FlagName << "\n";
}
+ Str << "revision_" << getSubzeroRevision() << "\n";
}
} // end of anonymous namespace
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 349db7c..678c521 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -23,6 +23,7 @@
#include "IceGlobalInits.h"
#include "IceLiveness.h"
#include "IceOperand.h"
+#include "IceRevision.h"
#include "IceTargetLowering.h"
#include "IceTimerTree.h"
#include "IceTypes.def"
@@ -357,6 +358,18 @@
#undef X
TargetLowering::staticInit(this);
+
+ if (getFlags().getEmitRevision()) {
+ // Embed the Subzero revision into the compiled binary by creating a special
+ // global variable initialized with the revision string.
+ auto *Revision = VariableDeclaration::create(&Globals, true);
+ Revision->setName(this, "__Sz_revision");
+ Revision->setIsConstant(true);
+ const char *RevisionString = getSubzeroRevision();
+ Revision->addInitializer(VariableDeclaration::DataInitializer::create(
+ &Globals, RevisionString, 1 + strlen(RevisionString)));
+ Globals.push_back(Revision);
+ }
}
void GlobalContext::translateFunctions() {
diff --git a/src/IceRevision.cpp b/src/IceRevision.cpp
new file mode 100644
index 0000000..b8233d0
--- /dev/null
+++ b/src/IceRevision.cpp
@@ -0,0 +1,28 @@
+//===- subzero/src/IceRevision.cpp - Revision string embedding ------------===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Implements the function for returning the Subzero revision string.
+///
+//===----------------------------------------------------------------------===//
+
+#include "IceRevision.h"
+
+#define XSTRINGIFY(x) STRINGIFY(x)
+#define STRINGIFY(x) #x
+
+#ifndef SUBZERO_REVISION
+#define SUBZERO_REVISION unknown
+#endif // !SUBZERO_REVISION
+
+namespace Ice {
+const char *getSubzeroRevision() {
+ return "Subzero_revision_" XSTRINGIFY(SUBZERO_REVISION);
+}
+} // end of namespace Ice
diff --git a/src/IceRevision.h b/src/IceRevision.h
new file mode 100644
index 0000000..170755b
--- /dev/null
+++ b/src/IceRevision.h
@@ -0,0 +1,32 @@
+//===- subzero/src/IceRevision.h - Revision string embedding ----*- C++ -*-===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Declares the function for returning the Subzero revision string.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEREVISION_H
+#define SUBZERO_SRC_ICEREVISION_H
+
+namespace Ice {
+
+// Returns the Subzero revision string, which is meant to be essentially the git
+// hash of the repo when Subzero was built.
+//
+// Note: It would be possible to declare this a constexpr char[] and put its
+// definition right here in the include file. But since the git hash is passed
+// to the compiler on the command line, and compilation is directed through a
+// Makefile, lack of recompilation could lead to different files seeing
+// inconsistent revision strings.
+const char *getSubzeroRevision();
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEREVISION_H