Учитывая статистику GIMPLE Call, которая имеет два аргумента, я хочу добавить третий, как? - PullRequest
3 голосов
/ 06 мая 2019

Я должен сделать некоторые манипуляции с оператором GIMPLE_CALL.Этот GIMPLE_CALL будет иметь два аргумента, например: foo (a, b).Моя цель - изменить этот метод на другой метод, имеющий ТРИ аргумента, например, zoo (a, b, c)

В моем текущем подходе сбой GCC во время компиляции примера исходной программы.

Мой код работает, когда все, что я делаю, это заменяю имя метода (т.е. не меняю номера аргументов).

Кроме того, мне не удалось найти какие-либо методы, предназначенные для добавления / удаления номеров аргументов для GIMPLE_CALL.Что приводит меня к мысли, что это может быть неправильный подход.

Код:

   //Getting the current number of  Call Arguments from target GIMPLE               
   //statememt
   unsigned num_of_ops = gimple_call_num_args(stmt);

   //Replace the method name to a new Method   
   gimple_call_set_fndecl(stmt, new_method);


   //We need to increment total number of call arguments by 1
   //Total numer of arguments are, Number of CALL Arguments + 3
   //You can confirm this in definitions of gimple_call_num_args() and 
   //gimple_call_set_arg()
   gimple_set_num_ops(stmt,num_of_ops+3+1);


   //Add the new argument
   gimple_call_set_arg(stmt, num_of_ops, third_argument);
   update_stmt (stmt);

1 Ответ

1 голос
/ 06 мая 2019

Кажется, вы можете настроить num_ops только при таком подходе к меньшему значению.

gimple_set_num_ops - простой установщик, он не выделяет хранилище:

static inline void
gimple_set_num_ops (gimple *gs, unsigned num_ops)
{
  gs->num_ops = num_ops;
}

Вам придется создать еще один оператор GIMPLE.

Я думаю, это использование вкодовая база GCC решает ту же проблему, что и у вас (от gcc/gimple.c):

/* Set the RHS of assignment statement pointed-to by GSI to CODE with
   operands OP1, OP2 and OP3.

   NOTE: The statement pointed-to by GSI may be reallocated if it
   did not have enough operand slots.  */

void
gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *gsi, enum tree_code code,
                tree op1, tree op2, tree op3)
{
  unsigned new_rhs_ops = get_gimple_rhs_num_ops (code);
  gimple *stmt = gsi_stmt (*gsi);
  gimple *old_stmt = stmt;

  /* If the new CODE needs more operands, allocate a new statement.  */
  if (gimple_num_ops (stmt) < new_rhs_ops + 1)
    {
      tree lhs = gimple_assign_lhs (old_stmt);
      stmt = gimple_alloc (gimple_code (old_stmt), new_rhs_ops + 1);
      memcpy (stmt, old_stmt, gimple_size (gimple_code (old_stmt)));
      gimple_init_singleton (stmt);

      /* The LHS needs to be reset as this also changes the SSA name
     on the LHS.  */
      gimple_assign_set_lhs (stmt, lhs);
    }

  gimple_set_num_ops (stmt, new_rhs_ops + 1);
  gimple_set_subcode (stmt, code);
  gimple_assign_set_rhs1 (stmt, op1);
  if (new_rhs_ops > 1)
    gimple_assign_set_rhs2 (stmt, op2);
  if (new_rhs_ops > 2)
    gimple_assign_set_rhs3 (stmt, op3);
  if (stmt != old_stmt)
    gsi_replace (gsi, stmt, false);
}
...