Subzero: Initial implementation of multithreaded translation.
Provides a single-producer, multiple-consumer translation queue where the number of translation threads is given by the -threads=N argument. The producer (i.e., bitcode parser) blocks if the queue size is >=N, in order to control the memory footprint. If N=0 (which is the default), execution is purely single-threaded. If N=1, there is a single translation thread running in parallel with the parser thread. "make check" succeeds with the default changed to N=1.
Currently emission is also done by the translation thread, which limits scalability since the emit stream has to be locked. Also, since the ELF writer stream is not locked, it won't be safe to use N>1 with the ELF writer. Furthermore, for N>1, emitted function ordering is nondeterministic and needs to be recombobulated. This will all be fixed in a follow-on CL.
The -timing option is broken for N>0. This will be fixed in a follow-on CL.
Verbose flags are now managed in the Cfg instead of (or in addition to) the GlobalContext, due to the -verbose-focus option which wants to temporarily change the verbose level for a particular function.
TargetLowering::emitConstants() and related methods are changed to be static, so that a valid TargetLowering object isn't required. This is because the TargetLowering object wants to hold a valid Cfg, and none really exists after all functions are translated and the constant pool is ready for emission.
The Makefile.standalone now has a TSAN=1 option to enable ThreadSanitizer.
BUG= none
R=jfb@chromium.org
Review URL: https://codereview.chromium.org/870653002
diff --git a/src/IceCfg.h b/src/IceCfg.h
index 472ba79..5f827f5 100644
--- a/src/IceCfg.h
+++ b/src/IceCfg.h
@@ -15,8 +15,6 @@
#ifndef SUBZERO_SRC_ICECFG_H
#define SUBZERO_SRC_ICECFG_H
-#include <memory>
-
#include "assembler.h"
#include "IceClFlags.h"
#include "IceDefs.h"
@@ -42,6 +40,7 @@
}
// Gets a pointer to the current thread's Cfg.
static const Cfg *getCurrentCfg() { return ICE_TLS_GET_FIELD(CurrentCfg); }
+ void updateTLS() const { ICE_TLS_SET_FIELD(CurrentCfg, this); }
// Gets a pointer to the current thread's Cfg's allocator.
static ArenaAllocator<> *getCurrentCfgAllocator() {
assert(ICE_TLS_GET_FIELD(CurrentCfg));
@@ -50,6 +49,12 @@
GlobalContext *getContext() const { return Ctx; }
+ // Returns true if any of the specified options in the verbose mask
+ // are set. If the argument is omitted, it checks if any verbose
+ // options at all are set.
+ bool isVerbose(VerboseMask Mask = IceV_All) const { return VMask & Mask; }
+ void setVerbose(VerboseMask Mask) { VMask = Mask; }
+
// Manage the name and return type of the function being translated.
void setFunctionName(const IceString &Name) { FunctionName = Name; }
IceString getFunctionName() const { return FunctionName; }
@@ -184,6 +189,7 @@
Cfg(GlobalContext *Ctx);
GlobalContext *Ctx;
+ VerboseMask VMask;
IceString FunctionName;
Type ReturnType;
bool IsInternalLinkage;