@@ -226,36 +226,39 @@ class aie_row_topology_directive: public directive
226226 aie_row_topology_directive& operator =(aie_row_topology_directive&&) = default ;
227227};
228228
229- // Filename intern table: maps each unique source-file name to a compact 32-bit index.
230- // thread_local: It means each thread gets its own separate copy of the table,
231- // which keeps concurrent parse jobs on different threads isolated.
232- // The table is never cleared; indices remain valid as long as the thread is alive,
233- // which always outlives any asm_data objects created on that thread.
234- // inline: This global variable can be defined in multiple translation units without
235- // violating the One Definition Rule (ODR).
229+ // Per-parser filename intern table: maps each unique source-file name to a compact
230+ // 32-bit index. One table per asm_parser so config.json instances do not share indices.
236231namespace detail {
237- inline thread_local std::vector<std::string> g_filename_table;
238- inline thread_local std::unordered_map<std::string, uint32_t > g_filename_index;
232+ class filename_table {
233+ std::vector<std::string> m_table;
234+ std::unordered_map<std::string, uint32_t > m_index;
235+ uint32_t m_default_idx = static_cast <uint32_t >(-1 );
239236
240- inline uint32_t intern_filename (const std::string& fname) {
241- auto it = g_filename_index.find (fname);
242- if (it != g_filename_index.end ())
237+ public:
238+ uint32_t intern_filename (const std::string& fname) {
239+ auto it = m_index.find (fname);
240+ if (it != m_index.end ())
243241 return it->second ;
244- const auto idx = static_cast <uint32_t >(g_filename_table .size ());
245- g_filename_table .push_back (fname);
246- g_filename_index .emplace (g_filename_table .back (), idx);
242+ const auto idx = static_cast <uint32_t >(m_table .size ());
243+ m_table .push_back (fname);
244+ m_index .emplace (m_table .back (), idx);
247245 return idx;
248246 }
249247
250- inline const std::string& lookup_filename (uint32_t idx) {
251- return g_filename_table [idx];
248+ const std::string& lookup_filename (uint32_t idx) const {
249+ return m_table [idx];
252250 }
253251
254- // Cached index for synthetic ops that are not tied to a real source path.
255- inline uint32_t default_source_file_idx () {
256- thread_local const uint32_t idx = intern_filename (std::string (" default" ));
257- return idx;
252+ bool is_filename_seen (const std::string& fname) const {
253+ return m_index.find (fname) != m_index.end ();
254+ }
255+
256+ uint32_t default_source_file_idx () {
257+ if (m_default_idx == static_cast <uint32_t >(-1 ))
258+ m_default_idx = intern_filename (std::string (" default" ));
259+ return m_default_idx;
258260 }
261+ };
259262} // namespace detail
260263
261264class asm_data
@@ -267,7 +270,7 @@ class asm_data
267270 pageid_type m_pagenum;
268271 uint32_t m_linenumber;
269272 // m_line removed: assembly text is reconstructed on demand via get_line().
270- // m_file replaced with a 32-bit index into a thread_local intern table .
273+ // m_file replaced with a 32-bit index into the owning parser's filename_table .
271274 uint32_t m_file_idx;
272275 int m_annotation_index = -1 ;
273276
@@ -294,7 +297,9 @@ class asm_data
294297 HEADER_ACCESS_GET_SET (offset_type, size);
295298 HEADER_ACCESS_GET_SET (pageid_type, pagenum);
296299 HEADER_ACCESS_GET_SET (uint32_t , linenumber);
297- const std::string& get_file () const { return detail::lookup_filename (m_file_idx); }
300+ const std::string& get_file (const detail::filename_table& table) const {
301+ return table.lookup_filename (m_file_idx);
302+ }
298303 uint32_t get_file_idx () const { return m_file_idx; }
299304 // Qualify the operation's own name as a label-map key (e.g. "0:start_job").
300305 std::string get_qualify_op_name () const {
@@ -512,7 +517,7 @@ class asm_parser: public std::enable_shared_from_this<asm_parser>
512517 std::map<int , std::vector<std::string>> m_preempt_hintmaps; // group -> vector of hintmap_labels (multiple PREEMPT opcodes per group)
513518 std::map<std::string, std::pair<std::string, std::string>> m_hintmap_labels; // hintmap_label -> (save_label, restore_label)
514519 std::set<int > m_preempt_without_hintmap; // groups that have PREEMPT opcodes without hintmaps
515- std::set<std::string> m_seen_files; // tracks included file names to detect duplicates
520+ detail::filename_table m_filename_table;
516521
517522 // One unique scratchpad region: all hintmap labels that share the same scratchbase+size
518523 struct hintmap_group_entry {
@@ -768,8 +773,6 @@ class asm_parser: public std::enable_shared_from_this<asm_parser>
768773 std::string get_current_label () const { return m_current_label; }
769774 const file_artifact* get_artifacts () const { return m_artifacts;}
770775
771- // Register filename as seen; returns true on first visit, false if already seen (duplicate).
772- bool add_seen_file (const std::string& filename) { return m_seen_files.insert (filename).second ; }
773776
774777 std::string top_label () const
775778 {
@@ -823,6 +826,20 @@ class asm_parser: public std::enable_shared_from_this<asm_parser>
823826
824827 void set_aie_row_topology_is_set (bool val) { m_aie_row_topology->set_is_set (val); }
825828
829+ const detail::filename_table& get_filename_table () const { return m_filename_table; }
830+
831+ uint32_t intern_filename (const std::string& fname) {
832+ return m_filename_table.intern_filename (fname);
833+ }
834+
835+ bool is_filename_seen (const std::string& fname) const {
836+ return m_filename_table.is_filename_seen (fname);
837+ }
838+
839+ uint32_t default_source_file_idx () {
840+ return m_filename_table.default_source_file_idx ();
841+ }
842+
826843 void parse_lines ();
827844
828845 void parse_lines (const std::vector<char >& data, std::string& file);
0 commit comments