Commit a9a92a5e by Nicolas Capens Committed by Nicolas Capens

Fix initializing the allocator before creating empty vector.

MSVC's implementation of the STL allocates memory even for an empty vector. Since we're using a custom thread-local allocator, it should be initialized before any STL member containers get initialized. BUG=swiftshader:7 Change-Id: I4bd977e7ee8eb87006fe08b051cbcfc9bc62342b Reviewed-on: https://chromium-review.googlesource.com/381531Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarJim Stichnoth <stichnot@chromium.org>
parent 86e5d883
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include "IceELFObjectWriter.h" #include "IceELFObjectWriter.h"
#include "IceGlobalInits.h" #include "IceGlobalInits.h"
#include "IceInst.h" #include "IceInst.h"
#include "IceInstrumentation.h"
#include "IceInstVarIter.h" #include "IceInstVarIter.h"
#include "IceInstrumentation.h"
#include "IceLiveness.h" #include "IceLiveness.h"
#include "IceLoopAnalyzer.h" #include "IceLoopAnalyzer.h"
#include "IceOperand.h" #include "IceOperand.h"
...@@ -35,9 +35,9 @@ ...@@ -35,9 +35,9 @@
namespace Ice { namespace Ice {
Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber) Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber)
: Ctx(Ctx), SequenceNumber(SequenceNumber), VMask(getFlags().getVerbose()), : Allocator(createAllocator()), Ctx(Ctx), SequenceNumber(SequenceNumber),
FunctionName(), NextInstNumber(Inst::NumberInitial), Live(nullptr) { VMask(getFlags().getVerbose()), FunctionName(),
Allocator.reset(new ArenaAllocator()); NextInstNumber(Inst::NumberInitial), Live(nullptr) {
NodeStrings.reset(new StringPool); NodeStrings.reset(new StringPool);
VarStrings.reset(new StringPool); VarStrings.reset(new StringPool);
CfgLocalAllocatorScope _(this); CfgLocalAllocatorScope _(this);
...@@ -65,6 +65,15 @@ Cfg::~Cfg() { ...@@ -65,6 +65,15 @@ Cfg::~Cfg() {
} }
} }
// Called in the initalizer list of Cfg's constructor to create the Allocator
// and set it as TLS before any other member fields are constructed, since they
// may depend on it.
ArenaAllocator *Cfg::createAllocator() {
ArenaAllocator *Allocator = new ArenaAllocator();
CfgAllocatorTraits::set_current(Allocator);
return Allocator;
}
/// Create a string like "foo(i=123:b=9)" indicating the function name, number /// Create a string like "foo(i=123:b=9)" indicating the function name, number
/// of high-level instructions, and number of basic blocks. This string is only /// of high-level instructions, and number of basic blocks. This string is only
/// used for dumping and other diagnostics, and the idea is that given a set of /// used for dumping and other diagnostics, and the idea is that given a set of
......
...@@ -31,6 +31,8 @@ class Cfg { ...@@ -31,6 +31,8 @@ class Cfg {
Cfg(const Cfg &) = delete; Cfg(const Cfg &) = delete;
Cfg &operator=(const Cfg &) = delete; Cfg &operator=(const Cfg &) = delete;
std::unique_ptr<ArenaAllocator> Allocator;
public: public:
~Cfg(); ~Cfg();
...@@ -306,6 +308,8 @@ private: ...@@ -306,6 +308,8 @@ private:
CfgVector<Inst *> CfgVector<Inst *>
findLoopInvariantInstructions(const CfgUnorderedSet<SizeT> &Body); findLoopInvariantInstructions(const CfgUnorderedSet<SizeT> &Body);
static ArenaAllocator *createAllocator();
GlobalContext *Ctx; GlobalContext *Ctx;
uint32_t SequenceNumber; /// output order for emission uint32_t SequenceNumber; /// output order for emission
OptLevel OptimizationLevel = Opt_m1; OptLevel OptimizationLevel = Opt_m1;
...@@ -323,7 +327,6 @@ private: ...@@ -323,7 +327,6 @@ private:
VarList Variables; VarList Variables;
VarList Args; /// subset of Variables, in argument order VarList Args; /// subset of Variables, in argument order
VarList ImplicitArgs; /// subset of Variables VarList ImplicitArgs; /// subset of Variables
std::unique_ptr<ArenaAllocator> Allocator;
// Separate string pools for CfgNode and Variable names, due to a combination // Separate string pools for CfgNode and Variable names, due to a combination
// of the uniqueness requirement, and assumptions in lit tests. // of the uniqueness requirement, and assumptions in lit tests.
std::unique_ptr<StringPool> NodeStrings; std::unique_ptr<StringPool> NodeStrings;
......
...@@ -31,9 +31,17 @@ CfgAllocatorTraits::allocator_type CfgAllocatorTraits::current() { ...@@ -31,9 +31,17 @@ CfgAllocatorTraits::allocator_type CfgAllocatorTraits::current() {
void CfgAllocatorTraits::set_current(const manager_type *Manager) { void CfgAllocatorTraits::set_current(const manager_type *Manager) {
ArenaAllocator *Allocator = ArenaAllocator *Allocator =
Manager == nullptr ? nullptr : Manager->Allocator.get(); Manager == nullptr ? nullptr : Manager->Allocator.get();
set_current(Allocator);
}
void CfgAllocatorTraits::set_current(ArenaAllocator *Allocator) {
ICE_TLS_SET_FIELD(CfgAllocator, Allocator); ICE_TLS_SET_FIELD(CfgAllocator, Allocator);
} }
void CfgAllocatorTraits::set_current(nullptr_t) {
ICE_TLS_SET_FIELD(CfgAllocator, nullptr);
}
ICE_TLS_DEFINE_FIELD(ArenaAllocator *, LivenessAllocatorTraits, ICE_TLS_DEFINE_FIELD(ArenaAllocator *, LivenessAllocatorTraits,
LivenessAllocator); LivenessAllocator);
......
...@@ -143,6 +143,8 @@ public: ...@@ -143,6 +143,8 @@ public:
static allocator_type current(); static allocator_type current();
static void set_current(const manager_type *Manager); static void set_current(const manager_type *Manager);
static void set_current(ArenaAllocator *Allocator);
static void set_current(nullptr_t);
private: private:
ICE_TLS_DECLARE_FIELD(ArenaAllocator *, CfgAllocator); ICE_TLS_DECLARE_FIELD(ArenaAllocator *, CfgAllocator);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment