diff options
author | torvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-30 17:12:13 +0000 |
---|---|---|
committer | torvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-30 17:12:13 +0000 |
commit | 53aaf755f28955aa98bc0720828a09776808f460 (patch) | |
tree | b6e99417fd098ac9a3612e23c5f9b04e219583bb | |
parent | 6f3b93c949b76c3abb6fbd5c6333c43185fbbefd (diff) | |
download | gcc-53aaf755f28955aa98bc0720828a09776808f460.tar.gz |
Removed unnecessary trycommit, rollback, and registerThrownObject ABI functions.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/transactional-memory@175716 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libitm/ChangeLog | 13 | ||||
-rw-r--r-- | libitm/barrier.cc | 3 | ||||
-rw-r--r-- | libitm/beginend.cc | 23 | ||||
-rw-r--r-- | libitm/config/x86/x86_avx.cc | 2 | ||||
-rw-r--r-- | libitm/config/x86/x86_sse.cc | 4 | ||||
-rw-r--r-- | libitm/dispatch.h | 34 | ||||
-rw-r--r-- | libitm/libitm.h | 7 | ||||
-rw-r--r-- | libitm/libitm.map | 3 | ||||
-rw-r--r-- | libitm/libitm.texi | 65 | ||||
-rw-r--r-- | libitm/libitm_i.h | 4 | ||||
-rw-r--r-- | libitm/method-serial.cc | 12 |
11 files changed, 97 insertions, 73 deletions
diff --git a/libitm/ChangeLog b/libitm/ChangeLog index 7459fa2afbc..4d800007cbe 100644 --- a/libitm/ChangeLog +++ b/libitm/ChangeLog @@ -1,10 +1,21 @@ 2011-06-30 Torvald Riegel <triegel@redhat.com> + * libitm_i.h (STATE_ABORTING): Remove. + * beginend.cc (_ITM_abortTransaction): Same. + (GTM::gtm_transaction::trycommit_and_finalize): Same. + * libitm.h (_ITM_registerThrownObject, _ITM_tryCommitTransaction): Remove. + (_ITM_rollbackTransaction): Remove. + * beginend.cc: Same. + * libitm.map: Same. + * libitm.texi: Document these ABI changes. + +2011-06-30 Torvald Riegel <triegel@redhat.com> + * libitm.texi: New file. * Makefile.am: Add libitm.texi. * Makefile.in: Rebuild. -2011-05-25 Torvald Riegel <triegel@redhat.com> +2011-06-30 Torvald Riegel <triegel@redhat.com> * libitm_i.h: Move parts to common.h and dispatch.h. * common.h: New file. diff --git a/libitm/barrier.cc b/libitm/barrier.cc index 10424d03fba..de84e04f7e9 100644 --- a/libitm/barrier.cc +++ b/libitm/barrier.cc @@ -40,6 +40,5 @@ bool abi_dispatch::memmove_overlap_check(void *dst, const void *src, return true; } -CREATE_DISPATCH_FUNCTIONS(GTM::abi_disp()->_, ) -//CREATE_DISPATCH_FUNCTIONS(GTM::abi_dispatch::_, _static) +CREATE_DISPATCH_FUNCTIONS(GTM::abi_disp()->, ) diff --git a/libitm/beginend.cc b/libitm/beginend.cc index 7ed5073a662..9b16973b2a4 100644 --- a/libitm/beginend.cc +++ b/libitm/beginend.cc @@ -184,25 +184,12 @@ GTM::gtm_transaction::rollback () } void ITM_REGPARM -_ITM_rollbackTransaction (void) -{ - gtm_transaction *tx = gtm_tx(); - - assert ((tx->prop & pr_hasNoAbort) == 0); - assert ((tx->state & gtm_transaction::STATE_ABORTING) == 0); - - tx->rollback (); - tx->state |= gtm_transaction::STATE_ABORTING; -} - -void ITM_REGPARM _ITM_abortTransaction (_ITM_abortReason reason) { gtm_transaction *tx = gtm_tx(); assert (reason == userAbort); assert ((tx->prop & pr_hasNoAbort) == 0); - assert ((tx->state & gtm_transaction::STATE_ABORTING) == 0); if (tx->state & gtm_transaction::STATE_IRREVOCABLE) abort (); @@ -238,7 +225,7 @@ GTM::gtm_transaction::trycommit () bool GTM::gtm_transaction::trycommit_and_finalize () { - if ((this->state & gtm_transaction::STATE_ABORTING) || trycommit ()) + if (trycommit ()) { abi_disp()->fini (); set_gtm_tx (this->prev); @@ -252,14 +239,6 @@ GTM::gtm_transaction::trycommit_and_finalize () return false; } -bool ITM_REGPARM -_ITM_tryCommitTransaction (void) -{ - gtm_transaction *tx = gtm_tx(); - assert ((tx->state & gtm_transaction::STATE_ABORTING) == 0); - return tx->trycommit (); -} - void ITM_NORETURN GTM::gtm_transaction::restart (gtm_restart_reason r) { diff --git a/libitm/config/x86/x86_avx.cc b/libitm/config/x86/x86_avx.cc index f81e3b8f59a..1f4ea538837 100644 --- a/libitm/config/x86/x86_avx.cc +++ b/libitm/config/x86/x86_avx.cc @@ -27,7 +27,7 @@ // ??? Use memcpy for now, until we have figured out how to best instantiate // these loads/stores. -CREATE_DISPATCH_FUNCTIONS_T_MEMCPY(M256, GTM::abi_disp()->_, ) +CREATE_DISPATCH_FUNCTIONS_T_MEMCPY(M256, GTM::abi_disp()->, ) void ITM_REGPARM _ITM_LM256 (const _ITM_TYPE_M256 *ptr) diff --git a/libitm/config/x86/x86_sse.cc b/libitm/config/x86/x86_sse.cc index a8585e4759d..7440c949cb7 100644 --- a/libitm/config/x86/x86_sse.cc +++ b/libitm/config/x86/x86_sse.cc @@ -27,8 +27,8 @@ // ??? Use memcpy for now, until we have figured out how to best instantiate // these loads/stores. -CREATE_DISPATCH_FUNCTIONS_T_MEMCPY(M64, GTM::abi_disp()->_, ) -CREATE_DISPATCH_FUNCTIONS_T_MEMCPY(M128, GTM::abi_disp()->_, ) +CREATE_DISPATCH_FUNCTIONS_T_MEMCPY(M64, GTM::abi_disp()->, ) +CREATE_DISPATCH_FUNCTIONS_T_MEMCPY(M128, GTM::abi_disp()->, ) void ITM_REGPARM _ITM_LM64 (const _ITM_TYPE_M64 *ptr) diff --git a/libitm/dispatch.h b/libitm/dispatch.h index 955cfabf0f6..3643503b5f7 100644 --- a/libitm/dispatch.h +++ b/libitm/dispatch.h @@ -32,24 +32,24 @@ // use M2 to create separate methods names for virtual and static) // The _PV variants are for the pure-virtual methods in the base class. #define ITM_READ_M(T, LSMOD, M, M2) \ - M _ITM_TYPE_##T ITM_REGPARM _ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr)\ + M _ITM_TYPE_##T ITM_REGPARM ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr) \ { \ return load(ptr, abi_dispatch::LSMOD); \ } #define ITM_READ_M_PV(T, LSMOD, M, M2) \ - M _ITM_TYPE_##T ITM_REGPARM _ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr)\ + M _ITM_TYPE_##T ITM_REGPARM ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr) \ = 0; #define ITM_WRITE_M(T, LSMOD, M, M2) \ - M void ITM_REGPARM _ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr,\ + M void ITM_REGPARM ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr, \ _ITM_TYPE_##T val) \ { \ store(ptr, val, abi_dispatch::LSMOD); \ } #define ITM_WRITE_M_PV(T, LSMOD, M, M2) \ - M void ITM_REGPARM _ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr,\ + M void ITM_REGPARM ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr, \ _ITM_TYPE_##T val) \ = 0; @@ -99,20 +99,20 @@ // Creates memcpy/memmove/memset methods. #define CREATE_DISPATCH_METHODS_MEM() \ -virtual void _memtransfer(void *dst, const void* src, size_t size, \ +virtual void memtransfer(void *dst, const void* src, size_t size, \ bool may_overlap, ls_modifier dst_mod, ls_modifier src_mod) \ { \ - _memtransfer_static(dst, src, size, may_overlap, dst_mod, src_mod); \ + memtransfer_static(dst, src, size, may_overlap, dst_mod, src_mod); \ } \ -virtual void _memset(void *dst, int c, size_t size, ls_modifier mod) \ +virtual void memset(void *dst, int c, size_t size, ls_modifier mod) \ { \ - _memset_static(dst, c, size, mod); \ + memset_static(dst, c, size, mod); \ } #define CREATE_DISPATCH_METHODS_MEM_PV() \ -virtual void _memtransfer(void *dst, const void* src, size_t size, \ +virtual void memtransfer(void *dst, const void* src, size_t size, \ bool may_overlap, ls_modifier dst_mod, ls_modifier src_mod) = 0; \ -virtual void _memset(void *dst, int c, size_t size, ls_modifier mod) = 0; +virtual void memset(void *dst, int c, size_t size, ls_modifier mod) = 0; // Creates ABI load/store functions that can target either a class or an @@ -120,13 +120,13 @@ virtual void _memset(void *dst, int c, size_t size, ls_modifier mod) = 0; #define ITM_READ(T, LSMOD, TARGET, M2) \ _ITM_TYPE_##T ITM_REGPARM _ITM_##LSMOD##T (const _ITM_TYPE_##T *ptr) \ { \ - return TARGET##ITM_##LSMOD##T##M2(ptr); \ + return TARGET ITM_##LSMOD##T##M2(ptr); \ } #define ITM_WRITE(T, LSMOD, TARGET, M2) \ void ITM_REGPARM _ITM_##LSMOD##T (_ITM_TYPE_##T *ptr, _ITM_TYPE_##T val) \ { \ - TARGET##ITM_##LSMOD##T##M2(ptr, val); \ + TARGET ITM_##LSMOD##T##M2(ptr, val); \ } // Creates ABI load/store functions for all load/store modifiers for a @@ -144,12 +144,12 @@ virtual void _memset(void *dst, int c, size_t size, ls_modifier mod) = 0; #define ITM_MEMTRANSFER_DEF(TARGET, M2, NAME, READ, WRITE) \ void ITM_REGPARM _ITM_memcpy##NAME(void *dst, const void *src, size_t size) \ { \ - TARGET##memtransfer##M2 (dst, src, size, \ + TARGET memtransfer##M2 (dst, src, size, \ false, GTM::abi_dispatch::WRITE, GTM::abi_dispatch::READ); \ } \ void ITM_REGPARM _ITM_memmove##NAME(void *dst, const void *src, size_t size) \ { \ - TARGET##memtransfer##M2 (dst, src, size, \ + TARGET memtransfer##M2 (dst, src, size, \ GTM::abi_dispatch::memmove_overlap_check(dst, src, size, \ GTM::abi_dispatch::WRITE, GTM::abi_dispatch::READ), \ GTM::abi_dispatch::WRITE, GTM::abi_dispatch::READ); \ @@ -158,7 +158,7 @@ void ITM_REGPARM _ITM_memmove##NAME(void *dst, const void *src, size_t size) \ #define ITM_MEMSET_DEF(TARGET, M2, WRITE) \ void ITM_REGPARM _ITM_memset##WRITE(void *dst, int c, size_t size) \ { \ - TARGET##memset##M2 (dst, c, size, GTM::abi_dispatch::WRITE); \ + TARGET memset##M2 (dst, c, size, GTM::abi_dispatch::WRITE); \ } \ @@ -210,7 +210,7 @@ void ITM_REGPARM _ITM_memset##WRITE(void *dst, int c, size_t size) \ _ITM_TYPE_##T ITM_REGPARM _ITM_##LSMOD##T (const _ITM_TYPE_##T *ptr)\ { \ _ITM_TYPE_##T v; \ - TARGET##memtransfer##M2(&v, ptr, sizeof(_ITM_TYPE_##T), false, \ + TARGET memtransfer##M2(&v, ptr, sizeof(_ITM_TYPE_##T), false, \ GTM::abi_dispatch::NONTXNAL, GTM::abi_dispatch::LSMOD); \ return v; \ } @@ -218,7 +218,7 @@ void ITM_REGPARM _ITM_memset##WRITE(void *dst, int c, size_t size) \ #define ITM_WRITE_MEMCPY(T, LSMOD, TARGET, M2) \ void ITM_REGPARM _ITM_##LSMOD##T (_ITM_TYPE_##T *ptr, _ITM_TYPE_##T val)\ { \ - TARGET##memtransfer##M2(ptr, &val, sizeof(_ITM_TYPE_##T), false, \ + TARGET memtransfer##M2(ptr, &val, sizeof(_ITM_TYPE_##T), false, \ GTM::abi_dispatch::LSMOD, GTM::abi_dispatch::NONTXNAL); \ } diff --git a/libitm/libitm.h b/libitm/libitm.h index df89d33242f..abd4274e608 100644 --- a/libitm/libitm.h +++ b/libitm/libitm.h @@ -45,7 +45,7 @@ extern "C" { #define ITM_NORETURN __attribute__((noreturn)) #define ITM_PURE __attribute__((transaction_pure)) - + /* The following are externally visible definitions and functions, though only very few of these should be called by user code. */ @@ -91,6 +91,7 @@ typedef enum pr_RaRBarriersOmitted = 0x0200, pr_undoLogCode = 0x0400, pr_preferUninstrumented = 0x0800, + /* Exception blocks are not used nor supported. */ pr_exceptionBlock = 0x1000, pr_readOnly = 0x4000, pr_hasElse = 0x200000, @@ -138,12 +139,8 @@ extern _ITM_transactionId_t _ITM_getTransactionId(void) ITM_REGPARM; extern uint32_t _ITM_beginTransaction(uint32_t, ...) ITM_REGPARM; extern void _ITM_abortTransaction(_ITM_abortReason) ITM_REGPARM ITM_NORETURN; -extern void _ITM_rollbackTransaction (void) ITM_REGPARM; extern void _ITM_commitTransaction (void) ITM_REGPARM; -extern bool _ITM_tryCommitTransaction(void) ITM_REGPARM; - -extern void _ITM_registerThrownObject (const void *, size_t) ITM_REGPARM; extern void _ITM_changeTransactionMode (_ITM_transactionState) ITM_REGPARM; diff --git a/libitm/libitm.map b/libitm/libitm.map index 0d52a7c85d3..49d0b1b5ebb 100644 --- a/libitm/libitm.map +++ b/libitm/libitm.map @@ -12,9 +12,6 @@ LIBITM_1.0 { _ITM_getTransactionId; _ITM_inTransaction; _ITM_libraryVersion; - _ITM_registerThrownObject; - _ITM_rollbackTransaction; - _ITM_tryCommitTransaction; _ITM_versionCompatible; _ITM_registerTMCloneTable; diff --git a/libitm/libitm.texi b/libitm/libitm.texi index 8d8de8c174c..046b0bdd85d 100644 --- a/libitm/libitm.texi +++ b/libitm/libitm.texi @@ -221,25 +221,34 @@ reported for the dynamic scope as well, not just for the lexical scope (@code{hasNoAbort}). Without this, a library cannot exploit this together with flat nesting. -@strong{TODO} @code{exceptionBlock?} +@code{exceptionBlock} is not supported because exception blocks are not used. @subsubsection [No changes] Windows exception state @subsubsection [No changes] Other machine state -@subsubsection Results from beginTransaction -@strong{TODO} @code{abortTransaction} supported? +@subsubsection [No changes] Results from beginTransaction @subsection Aborting a transaction -@strong{TODO} make consistent with EH. -@subsection Committing a transaction -@strong{TODO} make consistent with EH. +@code{_ITM_rollbackTransaction} is not supported. @code{_ITM_abortTransaction} +is supported but the abort reason @code{exceptionBlockAbort} is not (and there +are no exception blocks in general, so the related cases also do not have to +be considered). -@subsection Exception handling support +@subsection Committing a transaction -@strong{TODO} Document wrappers. Document code generated for commit, perhaps -with examples similar to those in the specification. What can be removed from -the ABI in turn? Document requirements on libstdc++ (@code{_cxa_tm_cleanup()}). +The exception handling (EH) scheme is different. The Intel ABI requires the +@code{_ITM_tryCommitTransaction} function that will return even when the +commit failed and will have to be matched with calls to either +@code{_ITM_abortTransaction} or @code{_ITM_commitTransaction}. In contrast, +gcc relies on transactional wrappers for the functions of the Exception +Handling ABI and on one additional commit function (shown below). This allows +the TM to keep track of EH internally and thus it does not have to embed the +cleanup of EH state into the existing EH code in the program. +@code{_ITM_tryCommitTransaction} is not supported. +@code{_ITM_commitTransactionToId} is also not supported because the +propagation of thrown exceptions will not bypass commits of nested +transactions. @example void _ITM_commitTransactionEH(void *exc_ptr) ITM_REGPARM; @@ -249,6 +258,42 @@ void *_ITM_cxa_begin_catch (void *exc_ptr); void _ITM_cxa_end_catch (void); @end example +@code{_ITM_commitTransactionEH} must be called to commit a transaction if an +exception could be in flight at this position in the code. @code{exc_ptr} is +the current exception or zero if there is no current exception. +The @code{_ITM_cxa...} functions are transactional wrappers for the respective +@code{__cxa...} functions and must be called instead of these in transactional +code. + +To support this EH scheme, libstdc++ needs to provide one additional function +(@code{_cxa_tm_cleanup}), which is used by the TM to clean up the exception +handling state while rolling back a transaction: + +@example +void __cxa_tm_cleanup (void *unthrown_obj, void *cleanup_exc, + unsigned int caught_count); +@end example + +@code{unthrown_obj} is non-null if the program called +@code{__cxa_allocate_exception} for this exception but did not yet called +@code{__cxa_throw} for it. @code{cleanup_exc} is non-null if the program is +currently processing a cleanup along an exception path but has not caught this +exception yet. @code{caught_count} is the nesting depth of +@code{__cxa_begin_catch} within the transaction (which can be counted by the TM +using @code{_ITM_cxa_begin_catch} and @code{_ITM_cxa_end_catch}); +@code{__cxa_tm_cleanup} then performs rollback by essentially performing +@code{__cxa_end_catch} that many times. + + + +@subsection Exception handling support + +Currently, there is no support for functionality like +@code{__transaction_cancel throw} as described in the C++ TM specification. +Supporting this should be possible with the EH scheme explained previously +because via the transactional wrappers for the EH ABI, the TM is able to +observe and intercept EH. + @subsection [No changes] Transition to serial--irrevocable mode @subsection [No changes] Data transfer functions diff --git a/libitm/libitm_i.h b/libitm/libitm_i.h index d323d45a382..98c2c753b06 100644 --- a/libitm/libitm_i.h +++ b/libitm/libitm_i.h @@ -146,10 +146,6 @@ struct gtm_transaction // Set if the serial-irrevocable dispatch table is installed. // Implies that no logging is being done, and abort is not possible. static const uint32_t STATE_IRREVOCABLE = 0x0002; - // Set if we're in the process of aborting the transaction. This is - // used when _ITM_rollbackTransaction is called to begin the abort - // and ends with _ITM_commitTransaction. - static const uint32_t STATE_ABORTING = 0x0004; // A bitmask of the above. uint32_t state; diff --git a/libitm/method-serial.cc b/libitm/method-serial.cc index 71208ec5dac..a6fbc7f6b5b 100644 --- a/libitm/method-serial.cc +++ b/libitm/method-serial.cc @@ -55,7 +55,8 @@ class serial_dispatch : public abi_dispatch *addr = value; } - static void _memtransfer_static(void *dst, const void* src, size_t size, + public: + static void memtransfer_static(void *dst, const void* src, size_t size, bool may_overlap, ls_modifier dst_mod, ls_modifier src_mod) { if (!may_overlap) @@ -64,7 +65,7 @@ class serial_dispatch : public abi_dispatch ::memmove(dst, src, size); } - static void _memset_static(void *dst, int c, size_t size, ls_modifier mod) + static void memset_static(void *dst, int c, size_t size, ls_modifier mod) { ::memset(dst, c, size); } @@ -72,7 +73,6 @@ class serial_dispatch : public abi_dispatch CREATE_DISPATCH_METHODS(virtual, ) CREATE_DISPATCH_METHODS_MEM() - public: virtual bool trycommit() { return true; } virtual void rollback() { abort(); } virtual void reinit() { } @@ -107,16 +107,16 @@ public: if (dst_mod != WaW && dst_mod != NONTXNAL) log(dst, size); if (!may_overlap) - memcpy(dst, src, size); + ::memcpy(dst, src, size); else - memmove(dst, src, size); + ::memmove(dst, src, size); } static void memset_static(void *dst, int c, size_t size, ls_modifier mod) { if (mod != WaW) log(dst, size); - memset(dst, c, size); + ::memset(dst, c, size); } // Local undo will handle this. |