简体   繁体   中英

Frama-C: find location of loop end

In the following example code:

void kernel(int ni, int nj, int nk, float alpha, float *tmp, float *A, float *B) {
int i, j, k;
  for (i = 0; i < ni; i++) {
    for (j = 0; j < nj; j++) {
      tmp[i * nj + j] = 0.0f;
      for (k = 0; k < nk; ++k) {
        tmp[i * nj + j] += alpha * A[i * nk + k] * B[k * nj + j];
      }
    }
}
}

I tried to get the location of } (which marks the end of each loop) without success.

  • For example, for the first loop, I looked into stmt.preds list and found just i = 0; and i++ . The stmt.succs list contain only the if test on i < ni .
  • } do not corresponds to any kind of stmt or Instr and does not exist in stmt.bstmts list.
  • Using functions in Stmts_graph like get_all_stmt_last_stmts (which give me a break statement and this break statement has the same location as the loop) don't solve the problem.

How can I get the location of my loop end (here } ). Thanks.

In Frama-C, there is no such thing as a statement which would correspond to the closing } in your code. Only statements that may have an observable effect (either on the memory, or on the control-flow) exist; the only exception is Skip , but Frama-C avoids generating those.

  • if you are looking for the line number of the } , as extracted from the AST, you may look at the second component of the locations that are attached to each statement. As can be seen in Cil_types , locations are pairs of Lexing.position , and the second one represents the end of the instruction. However Frama-C makes little effort to have an accurate information for this component, as it is never displayed

  • if you are looking for the AST statements that exit the loop, look for those that are inside the loop, and whose successor ( .succs field) are outside. This particular edge will correspond more or less to your } . In the loop of your example, you should find the break statement which is created to handle the exit condition.

to determine when loops start/stop use consistent indentation.

  1. indent after every opening brace '{'
  2. unindent before every closing brace '}'
  3. suggest each indent level be 4 spaces.

Applying the above criteria to the posted code results in:

void kernel(int ni, int nj, int nk, float alpha, float *tmp, float *A, float *B)
{
    int i, j, k;

    for (i = 0; i < ni; i++)
    {
        for (j = 0; j < nj; j++)
        {
            tmp[i * nj + j] = 0.0f;

            for (k = 0; k < nk; ++k)
            {
                tmp[i * nj + j] += alpha * A[i * nk + k] * B[k * nj + j];
            }
        }
    }
}

which is very easy to see where each loop starts and stops

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM