Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I slice an arbitrary function? #426

Open
shouguoyang opened this issue Feb 15, 2022 · 8 comments
Open

How can I slice an arbitrary function? #426

shouguoyang opened this issue Feb 15, 2022 · 8 comments
Labels

Comments

@shouguoyang
Copy link

If the criterion locates a non-main function, e.g. fact function below:

#include <stdio.h>

long int fact(int x)
{
        long int r = x;
        while (--x >=2)
                r *= x;

        return r;
}

int main(void)
{
        int a, b, c = 7;

        while (scanf("%d", &a) > 0) {
                assert(a > 0);
                printf("fact: %lu\n", fact(a));
        }

        return 0;
}

Compile it with clang-10 -S -emit-llvm -g -o fact.bc fact.c or clang-10 -c -emit-llvm -g -o fact.bc fact.c.
Slicing by ./llvm-slicer -entry fact -c 8:r fact.bc, the result shows

No reachable slicing criteria: '' '8:r'
[llvm-slicer] saving sliced module to: fact.sliced

How can I slice with the variable r at line 8?

@mchalupa
Copy link
Owner

Did you try to use -sc instead of -c? (-c is an older switch that is meant to get a name of a function). And I do not see any use of r at line 8. Did you mean line 9?

@mchalupa
Copy link
Owner

Ok, found the problem. There is a bug in the reachability slicer that runs before the main slicer. You can workaround it by using -cuttof-diverging=false. I.e., these commands should work:
llvm-slicer -c '9:r' -cutoff-diverging=false -entry fact fact.ll
or
llvm-slicer -sc '9#r' -cutoff-diverging=false -entry fact fact.ll

@mchalupa mchalupa added the bug label Feb 16, 2022
@shouguoyang
Copy link
Author

Thanks for your answer. I have some questions:

  1. why the results of forward slicing (e.g., ./llvm-slicer -sc "7#r" -cutoff-diverging=false -entry fact -forward fact.bc ) seems contain the code generated by backward slicing?
  • Forward slicing result:
5: {
6:      long int r = x;
7:      while (--x >=2)
8:              r *= x;
10:     return r;
11: }
  1. It appears that the results of backward slicing include code lines following the code line in criteria.
  2. If I specify a variable in criteria, let's say length at line N, at the same time variable start also at line N but not in criteria, the result code of slice seems to contain code lines that have data dependency on start. How can I just get the code that only have dependency on variable length precisely?

I would appreciate it if you could answer the questions above.

Btw, it would be more convenient if you could open a slack channel for this repo.

@mchalupa
Copy link
Owner

  1. why the results of forward slicing (e.g., ./llvm-slicer -sc "7#r" -cutoff-diverging=false -entry fact -forward fact.bc ) seems contain the code generated by backward slicing?

Because it does. It is to make the slice executable and LLVM code well-defined.

  1. It appears that the results of backward slicing include code lines following the code line in criteria.

Any example?

  1. If I specify a variable in criteria, let's say length at line N, at the same time variable start also at line N but not in criteria, the result code of slice seems to contain code lines that have data dependency on start. How can I just get the code that only have dependency on variable length precisely?

Again it would be nice to have a concrete example. Without it, I cannot tell where is the problem.

@mchalupa
Copy link
Owner

I moved the bug that started this conversation to #427 .

@shouguoyang
Copy link
Author

Let's say we get the code file fact.c below:

#include <assert.h>
#include <stdio.h>
int arr[10];
long int fact(int s, int e)
{
        int len = 10;
        if (s-e > len){
                return 0;
        }

        if (s+e > 20){
                return arr[s] - arr[e];
        }


        return arr[len - s];

}

int main(void)
{
        int a, b, c = 7;

        while (scanf("%d", &a) > 0) {
                assert(a > 0);
                printf("fact: %lu\n", fact(a, 1));
        }

        return 0;
}

I compiled the code by clang -emit-llvm -S -g -fno-discard-value-names fact.c -o fact.c.ll.
Then I did the slice by llvm-slicer -entry fact -sc "7#len" -cutoff-diverging=false -forward fact.c.ll.
I got the sliced code below:

5: {
6:      int len = 10;
7:      if (s-e > len){
8:              return 0;
9:      }
11:     if (s+e > 20){
12:             return arr[s] - arr[e];
13:     }
16:     return arr[len - s];
18: }

For the question 3, I specify the variable len in line 7 but get the code from lines 11 to 13, which has no control and data dependency with the criteria. So, could you explain why the code located at lines 11 to 13 is sliced? Is it possible to remove such code since it has no data or control dependency?

Regarding question 2, the slicer works well after specifying -cutoff-diverging=false* during the slicing process.

Thank you for your time.

@mchalupa
Copy link
Owner

For the question 3, I specify the variable len in line 7 but get the code from lines 11 to 13, which has no control and data dependency with the criteria. So, could you explain why the code located at lines 11 to 13 is sliced?

There is control dependence from line 7 to 11 and from 11 to 16. Line 11 (16, resp.) is not executed if the condition on line 7 (11, resp.) evaluates to true.

@shouguoyang
Copy link
Author

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants