[CPU/A64] Avoid static init order in A64 sequences
The A64 sequence table is populated by registration statics spread across multiple translation units. Keeping the backing map as a global object makes registration depend on cross-TU initialization order and can hit the table before it has been constructed. Move the sequence table behind a function-local static so sequence registration is safe regardless of which unit initializes first.
This commit is contained in:
@@ -35,7 +35,11 @@ namespace a64 {
|
|||||||
using namespace xe::cpu::hir;
|
using namespace xe::cpu::hir;
|
||||||
using namespace Xbyak_aarch64;
|
using namespace Xbyak_aarch64;
|
||||||
|
|
||||||
std::unordered_map<uint32_t, SequenceSelectFn> sequence_table;
|
std::unordered_map<uint32_t, SequenceSelectFn>& SequenceTable() {
|
||||||
|
static auto* sequence_table =
|
||||||
|
new std::unordered_map<uint32_t, SequenceSelectFn>();
|
||||||
|
return *sequence_table;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Debug validation helpers
|
// Debug validation helpers
|
||||||
@@ -4821,6 +4825,7 @@ static int anchor_vector_dest = anchor_vector;
|
|||||||
bool SelectSequence(A64Emitter* e, const hir::Instr* i,
|
bool SelectSequence(A64Emitter* e, const hir::Instr* i,
|
||||||
const hir::Instr** new_tail) {
|
const hir::Instr** new_tail) {
|
||||||
const InstrKey key(i);
|
const InstrKey key(i);
|
||||||
|
auto& sequence_table = SequenceTable();
|
||||||
auto it = sequence_table.find(key);
|
auto it = sequence_table.find(key);
|
||||||
if (it != sequence_table.end()) {
|
if (it != sequence_table.end()) {
|
||||||
if (it->second(*e, i, InstrKeyValue(key))) {
|
if (it->second(*e, i, InstrKeyValue(key))) {
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ namespace a64 {
|
|||||||
class A64Emitter;
|
class A64Emitter;
|
||||||
|
|
||||||
typedef bool (*SequenceSelectFn)(A64Emitter&, const hir::Instr*, uint32_t ikey);
|
typedef bool (*SequenceSelectFn)(A64Emitter&, const hir::Instr*, uint32_t ikey);
|
||||||
extern std::unordered_map<uint32_t, SequenceSelectFn> sequence_table;
|
std::unordered_map<uint32_t, SequenceSelectFn>& SequenceTable();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Register() {
|
bool Register() {
|
||||||
sequence_table.insert({T::head_key(), T::Select});
|
SequenceTable().insert({T::head_key(), T::Select});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user