| Index: src/IceGlobalContext.h
|
| diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
|
| index 6c6c22248c6fafd2cf5490c0c82cc545f9060484..05c4e272663d3f4b438b0b163d410b667168e028 100644
|
| --- a/src/IceGlobalContext.h
|
| +++ b/src/IceGlobalContext.h
|
| @@ -20,6 +20,7 @@
|
| #include "IceClFlags.h"
|
| #include "IceIntrinsics.h"
|
| #include "IceRNG.h"
|
| +#include "IceStringPool.h"
|
| #include "IceSwitchLowering.h"
|
| #include "IceTargetLowering.def"
|
| #include "IceThreading.h"
|
| @@ -53,30 +54,6 @@ enum class RuntimeHelper {
|
| H_Num
|
| };
|
|
|
| -/// LockedPtr is a way to provide automatically locked access to some object.
|
| -template <typename T> class LockedPtr {
|
| - LockedPtr() = delete;
|
| - LockedPtr(const LockedPtr &) = delete;
|
| - LockedPtr &operator=(const LockedPtr &) = delete;
|
| -
|
| -public:
|
| - LockedPtr(T *Value, GlobalLockType *Lock) : Value(Value), Lock(Lock) {
|
| - Lock->lock();
|
| - }
|
| - LockedPtr(LockedPtr &&Other) : Value(Other.Value), Lock(Other.Lock) {
|
| - Other.Value = nullptr;
|
| - Other.Lock = nullptr;
|
| - }
|
| - ~LockedPtr() { Lock->unlock(); }
|
| - T *operator->() const { return Value; }
|
| - T &operator*() const { return *Value; }
|
| - T *get() { return Value; }
|
| -
|
| -private:
|
| - T *Value;
|
| - GlobalLockType *Lock;
|
| -};
|
| -
|
| class GlobalContext {
|
| GlobalContext() = delete;
|
| GlobalContext(const GlobalContext &) = delete;
|
| @@ -113,7 +90,7 @@ class GlobalContext {
|
| for (uint32_t i = 0; i < Stats.size(); ++i)
|
| Stats[i] += Other.Stats[i];
|
| }
|
| - void dump(const IceString &Name, GlobalContext *Ctx);
|
| + void dump(const std::string &Name, GlobalContext *Ctx);
|
|
|
| private:
|
| std::array<uint32_t, CS_NUM> Stats;
|
| @@ -172,6 +149,7 @@ public:
|
| ELFStreamer *ELFStreamer);
|
| ~GlobalContext();
|
|
|
| + void dumpStrings();
|
| ///
|
| /// The dump, error, and emit streams need to be used by only one
|
| /// thread at a time. This is done by exclusively reserving the
|
| @@ -247,11 +225,12 @@ public:
|
| Constant *getConstantFloat(float Value);
|
| Constant *getConstantDouble(double Value);
|
| /// Returns a symbolic constant.
|
| - Constant *getConstantSym(const RelocOffsetT Offset,
|
| - const RelocOffsetArray &OffsetExpr,
|
| - const IceString &Name, const IceString &EmitString);
|
| - Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name);
|
| - Constant *getConstantExternSym(const IceString &Name);
|
| + Constant *getConstantSymWithEmitString(const RelocOffsetT Offset,
|
| + const RelocOffsetArray &OffsetExpr,
|
| + GlobalString Name,
|
| + const std::string &EmitString);
|
| + Constant *getConstantSym(RelocOffsetT Offset, GlobalString Name);
|
| + Constant *getConstantExternSym(GlobalString Name);
|
| /// Returns an undef.
|
| Constant *getConstantUndef(Type Ty);
|
| /// Returns a zero value.
|
| @@ -268,11 +247,12 @@ public:
|
| assert(Result != nullptr && "No such runtime helper function");
|
| return Result;
|
| }
|
| + GlobalString getGlobalString(const std::string &Name);
|
|
|
| /// Return a locked pointer to the registered jump tables.
|
| JumpTableDataList getJumpTables();
|
| /// Create a new jump table entry and return a reference to it.
|
| - JumpTableData &addJumpTable(const IceString &FuncName, SizeT Id,
|
| + JumpTableData &addJumpTable(GlobalString FuncName, SizeT Id,
|
| const JumpTableData::TargetList &TargetList);
|
|
|
| static const ClFlags &getFlags() { return Flags; }
|
| @@ -305,7 +285,7 @@ public:
|
| if (BuildDefs::dump())
|
| ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset();
|
| }
|
| - void dumpStats(const IceString &Name, bool Final = false);
|
| + void dumpStats(const std::string &Name, bool Final = false);
|
| void statsUpdateEmitted(uint32_t InstCount) {
|
| if (!getFlags().getDumpStats())
|
| return;
|
| @@ -356,24 +336,24 @@ public:
|
|
|
| /// newTimerStackID() creates a new TimerStack in the global space. It does
|
| /// not affect any TimerStack objects in TLS.
|
| - TimerStackIdT newTimerStackID(const IceString &Name);
|
| + TimerStackIdT newTimerStackID(const std::string &Name);
|
| /// dumpTimers() dumps the global timer data. As such, one probably wants to
|
| /// call mergeTimerStacks() as a prerequisite.
|
| void dumpTimers(TimerStackIdT StackID = TSK_Default,
|
| bool DumpCumulative = true);
|
| /// The following methods affect only the calling thread's TLS timer data.
|
| - TimerIdT getTimerID(TimerStackIdT StackID, const IceString &Name);
|
| + TimerIdT getTimerID(TimerStackIdT StackID, const std::string &Name);
|
| void pushTimer(TimerIdT ID, TimerStackIdT StackID);
|
| void popTimer(TimerIdT ID, TimerStackIdT StackID);
|
| void resetTimer(TimerStackIdT StackID);
|
| - void setTimerName(TimerStackIdT StackID, const IceString &NewName);
|
| + void setTimerName(TimerStackIdT StackID, const std::string &NewName);
|
|
|
| /// This is the first work item sequence number that the parser produces, and
|
| /// correspondingly the first sequence number that the emitter thread will
|
| /// wait for. Start numbering at 1 to leave room for a sentinel, in case e.g.
|
| /// we wish to inject items with a special sequence number that may be
|
| /// executed out of order.
|
| - static uint32_t getFirstSequenceNumber() { return 1; }
|
| + static constexpr uint32_t getFirstSequenceNumber() { return 1; }
|
| /// Adds a newly parsed and constructed function to the Cfg work queue.
|
| /// Notifies any idle workers that a new function is available for
|
| /// translating. May block if the work queue is too large, in order to control
|
| @@ -474,7 +454,7 @@ public:
|
| /// Uses DataLowering to lower Globals. Side effects:
|
| /// - discards the initializer list for the global variable in Globals.
|
| /// - clears the Globals array.
|
| - void lowerGlobals(const IceString &SectionSuffix);
|
| + void lowerGlobals(const std::string &SectionSuffix);
|
|
|
| /// Lowers the profile information.
|
| void lowerProfileData();
|
| @@ -486,10 +466,8 @@ public:
|
| /// function or symbol based on a command-line argument, such as changing the
|
| /// verbose level for a particular function. An empty Match argument means
|
| /// match everything. Returns true if there is a match.
|
| - static bool matchSymbolName(const IceString &SymbolName,
|
| - const IceString &Match) {
|
| - return Match.empty() || Match == SymbolName;
|
| - }
|
| + static bool matchSymbolName(const GlobalString &SymbolName,
|
| + const std::string &Match);
|
|
|
| static ClFlags Flags;
|
|
|
| @@ -505,49 +483,58 @@ public:
|
| }
|
| /// @}
|
|
|
| + LockedPtr<StringPool> getStrings() const {
|
| + return LockedPtr<StringPool>(Strings.get(), &StringsLock);
|
| + }
|
| +
|
| private:
|
| // Try to ensure mutexes are allocated on separate cache lines.
|
|
|
| // Destructors collaborate with Allocator
|
| ICE_CACHELINE_BOUNDARY;
|
| // Managed by getAllocator()
|
| - GlobalLockType AllocLock;
|
| + mutable GlobalLockType AllocLock;
|
| ArenaAllocator Allocator;
|
|
|
| ICE_CACHELINE_BOUNDARY;
|
| // Managed by getInitializerAllocator()
|
| - GlobalLockType InitAllocLock;
|
| + mutable GlobalLockType InitAllocLock;
|
| VariableDeclarationList Globals;
|
|
|
| ICE_CACHELINE_BOUNDARY;
|
| // Managed by getDestructors()
|
| using DestructorArray = std::vector<std::function<void()>>;
|
| - GlobalLockType DestructorsLock;
|
| + mutable GlobalLockType DestructorsLock;
|
| DestructorArray Destructors;
|
|
|
| ICE_CACHELINE_BOUNDARY;
|
| - // Managed by getConstantPool()
|
| - GlobalLockType ConstPoolLock;
|
| + // Managed by getStrings()
|
| + mutable GlobalLockType StringsLock;
|
| + std::unique_ptr<StringPool> Strings;
|
| +
|
| + ICE_CACHELINE_BOUNDARY;
|
| + // Managed by getConstPool()
|
| + mutable GlobalLockType ConstPoolLock;
|
| std::unique_ptr<ConstantPool> ConstPool;
|
|
|
| ICE_CACHELINE_BOUNDARY;
|
| // Managed by getJumpTableList()
|
| - GlobalLockType JumpTablesLock;
|
| + mutable GlobalLockType JumpTablesLock;
|
| JumpTableDataList JumpTableList;
|
|
|
| ICE_CACHELINE_BOUNDARY;
|
| // Managed by getErrorStatus()
|
| - GlobalLockType ErrorStatusLock;
|
| + mutable GlobalLockType ErrorStatusLock;
|
| ErrorCode ErrorStatus;
|
|
|
| ICE_CACHELINE_BOUNDARY;
|
| // Managed by getStatsCumulative()
|
| - GlobalLockType StatsLock;
|
| + mutable GlobalLockType StatsLock;
|
| CodeStats StatsCumulative;
|
|
|
| ICE_CACHELINE_BOUNDARY;
|
| // Managed by getTimers()
|
| - GlobalLockType TimerLock;
|
| + mutable GlobalLockType TimerLock;
|
| TimerList Timers;
|
|
|
| ICE_CACHELINE_BOUNDARY;
|
| @@ -663,7 +650,7 @@ public:
|
| if (BuildDefs::timers())
|
| pushCfg(Func);
|
| }
|
| - TimerMarker(GlobalContext *Ctx, const IceString &FuncName)
|
| + TimerMarker(GlobalContext *Ctx, const std::string &FuncName)
|
| : ID(getTimerIdFromFuncName(Ctx, FuncName)), Ctx(Ctx),
|
| StackID(GlobalContext::TSK_Funcs) {
|
| if (BuildDefs::timers())
|
| @@ -679,7 +666,7 @@ private:
|
| void push();
|
| void pushCfg(const Cfg *Func);
|
| static TimerIdT getTimerIdFromFuncName(GlobalContext *Ctx,
|
| - const IceString &FuncName);
|
| + const std::string &FuncName);
|
| const TimerIdT ID;
|
| GlobalContext *Ctx;
|
| const TimerStackIdT StackID;
|
|
|