On Mon, Aug 18, 2008 at 1:15 PM, Martin Schindewolf <[EMAIL PROTECTED]> wrote:
> Hi,
> I will try to explain in more detail:
> I am trying to implement support for transactions in GCC. In particular for
> a Software Transactional Memory library called tinySTM. Since transactions
> have the nice property that they can abort and execute again, we need some
> kind of checkpointing at the beginning of a transaction. The checkpointing
> is done two fold: on one hand setjmp is used to capture the register state
> on the other hand temporary variables are introduced by GCC to capture the
> value of live-in variables to the transaction and play the values back to
> the original variables in case of an abort. In terms of IR code a begin of a
> transaction is translated into this:
> <snip>  txn_handle.12_4 = __builtin_stm_new ();
>  jmp_buf.13_5 = __builtin_stm_get_env (txn_handle.12_4);
>  ssj_value.14_6 = _setjmp (jmp_buf.13_5);
>  if (ssj_value.14_6 == 0)
>   goto <bb 3> (<L1>);
>  else
>   goto <bb 4> (<L2>);
>  # SUCC: 4 (false) 3 (true)
>
>  # BLOCK 3
>  # PRED: 2 (true)
> <L1>:;
>  __builtin_printf ("SAVE_BB\n");
>  txn_save_m.19_15 = m_1;
>  txn_save_a.20_20 = a_2;
>  txn_save_b.21_25 = b_3;
>  fake_var.18_13 = __builtin_stm_dummy ("RECOVER_BB\n");
>  if (fake_var.18_13)
>   goto <bb 4> (<L2>);
>  else
>   goto <bb 5>;
>  # SUCC: 4 (true) 5 (false)
>
>  # BLOCK 4
>  # PRED: 2 (false) 3 (true)
>  # txn_save_b.21_26 = PHI <txn_save_b.21_24(2), txn_save_b.21_25(3)>
>  # txn_save_a.20_21 = PHI <txn_save_a.20_19(2), txn_save_a.20_20(3)>
>  # txn_save_m.19_16 = PHI <txn_save_m.19_14(2), txn_save_m.19_15(3)>
> <L2>:;
>  __builtin_printf ("RECOVER_BB\n");
>  m_17 = txn_save_m.19_16;
>  a_22 = txn_save_a.20_21;
>  b_27 = txn_save_b.21_26;
>  # SUCC: 5 (fallthru)
>
>  # BLOCK 5
>  # PRED: 4 (fallthru) 3 (false)
>  # m_18 = PHI <m_17(4), m_1(3)>
>  __builtin_stm_start (txn_handle.12_4, jmp_buf.13_5, &0);
> <snip here comes the begin of a transaction>
>
> the first part is acquiring a handle for the transactions from the STM, then
> a jump buffer is created by the STM and the setjmp is executed. Since the
> longjmp executed by the STM (in case of an abort) returns to this location,
> we simply evaluate the return value of the setjmp call and know what to
> execute. In case of returning from the call to setjmp we want to capture the
> values of the live-in variables, which are a,b and m in this example. In
> case we returned from a longjmp we want to restore the values from the
> temporary variables (txn_save_a/b/m) to the original variables (a/b/m).
> My problem with the SSA optimisations is that (after the SSA final_cleanup
> pass) in this example the initialisation of the variables a and b is moved
> into the SAVE_BB and RESTORE_BB basic blocks - both look like this:
>  a = 5;
>  b = 10;
> and the txn_save_* variables are optimised "away". Is there any way to
> prevent this kind of optimisations on SSA form for a particular group of
> variables? Here I would like to see the txn_save_* variables behave as a
> container for the values of the real variables and be sure that these
> variables are not touched by any optimisations.

Well, if you are inserting this abnormal control flow after going into SSA
then you need to make sure all SSA variables affected are marked
as SSA_NAME_OCCURS_IN_ABNORMAL_PHI and make sure that
SSA names from a single base variable not have overlapping life-ranges.

Which means what you are doing is not really going to be easy in
SSA form and you should rather try to do it before going into SSA.
And I would suggest you use the exception handling machinery of
GCC to do it and not insert setjmp/longjmp calls yourself or try to
track the complete program state.

Richard.

> Thank you very much for your ideas!
>
> Regards,
> Martin
>
>
>

Reply via email to