GCC Middle and Back End API Reference
|
Data Fields | |
tree | addr |
basic_block | entry_block |
vec< gimple * > | stmts |
tree | save_var |
Instead of instrumenting thread private memory, we save the addresses in a log which we later use to save/restore the addresses upon transaction start/restart. The log is keyed by address, where each element contains individual statements among different code paths that perform the store. This log is later used to generate either plain save/restore of the addresses upon transaction start/restart, or calls to the ITM_L* logging functions. So for something like: struct large { int x[1000]; }; struct large lala = { 0 }; __transaction { lala.x[i] = 123; ... } We can either save/restore: lala = { 0 }; trxn = _ITM_startTransaction (); if (trxn & a_saveLiveVariables) tmp_lala1 = lala.x[i]; else if (a & a_restoreLiveVariables) lala.x[i] = tmp_lala1; or use the logging functions: lala = { 0 }; trxn = _ITM_startTransaction (); _ITM_LU4 (&lala.x[i]); Obviously, if we use _ITM_L* to log, we prefer to call _ITM_L* as far up the dominator tree to shadow all of the writes to a given location (thus reducing the total number of logging calls), but not so high as to be called on a path that does not perform a write.
One individual log entry. We may have multiple statements for the same location if neither dominate each other (on different execution paths).
tree tm_log_entry::addr |
Referenced by log_entry_hasher::equal(), tm_log_add(), tm_log_emit(), tm_log_emit_restores(), tm_log_emit_saves(), and tm_log_emit_stmt().
basic_block tm_log_entry::entry_block |
Referenced by requires_barrier(), thread_private_new_memory(), tm_log_add(), tm_log_emit_restores(), and tm_log_emit_saves().
tree tm_log_entry::save_var |
Referenced by tm_log_add(), tm_log_emit(), tm_log_emit_restores(), and tm_log_emit_saves().
Referenced by log_entry_hasher::remove(), tm_log_add(), and tm_log_emit().