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

Dose this tool can do parameter slice #391

Open
Moriarty002 opened this issue May 11, 2021 · 8 comments
Open

Dose this tool can do parameter slice #391

Moriarty002 opened this issue May 11, 2021 · 8 comments
Labels

Comments

@Moriarty002
Copy link

If I want to slice only parameter with criterion , like below

static void 
C_bincount(double *x, R_xlen_t n, double *breaks, R_xlen_t nb, int *count,
	   int right, int include_border)
{
...
    for(i = 0 ; i < n ; i++)
	if(R_FINITE(x[i])) { // left in as a precaution
...
	    if(breaks[lo] <= x[i] &&
	       (x[i] < breaks[hi] || (x[i] == breaks[hi] && include_border))) {
		while(hi-lo >= 2) {
		    news = (hi+lo)/2;
		    if(x[i] > breaks[news] || (!right && x[i] == breaks[news]))
			lo = news;
		    else
			hi = news;
		}
...
	    }
	}
}

And I want to only get "breaks,hi,lo......" parameters which relate to variable x
Because the llvm-slicer can get "code" relate to x , I think there may be a way to find only related parameters

@mchalupa
Copy link
Owner

You should be able to get which parameters are relevant from the dependence graph, so yes, you can use DG to find that out.

@Moriarty002
Copy link
Author

Sorry , maybe my question is too obscure .
What I mean is "Is there an 'automatic' way" to do things above.

Find relevant parameters from dependence graph need to read output file and find it out manually .
And , when I try to use llvm-dda-dump , the output file is too large and hard to find relevant , or maybe I miss use?

 llvm-dda-dump --entry C_bincount --forward --dot --pta=fs -c=x test.bc > out.dot

the .bc file is generated from test.c

Because the png is too large to display and github not support svg , I can just put link here .
I don't know why the graph is so large , and how to search relevant parameters from that .

@mchalupa
Copy link
Owner

By getting the information from the dependence graph I meant to use the API of LLVMDependenceGraph and LLVMNode from C++ (but it would be probably also possible to parse the out.dot). So the answer is: no, there is no automatic way to do that.

or maybe I miss use?

You probably do not want to use llvm-dda-dump, but llvm-dg-dump or llvm-slicer -dump-dg. llvm-dda-dump does not dump the dependence graph, only the results of data dependence analysis (which is not the complete dependence graph).
And I am not sure about the --forward option. This option means that you want to get what is affected by variable x (+it adds also instructions to make the slice executable). From the discussion so far, I thought that you want to get parameters that can affect x (not that are affected by x).

the output file is too large

llvm-dg-dump has the parameter -func that makes it to dump only the given function.

@Moriarty002
Copy link
Author

Moriarty002 commented Sep 27, 2021

I am sure I want to get the variables affected by x , I wrote a tool using clang-frontend to get the variables from sliced code .
But the sliced code has no headers and I remove the declaration
For example
The original code

# 1 "tmp1.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 341 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "tmp1.c" 2

#include <R_ext/Arith.h>
#include <R_ext/Error.h>
#include <R_ext/Print.h>
#include <R_ext/Utils.h>
#include <Rinternals.h>
#include <Rmath.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
# 23 "tmp1.c"
#include <string.h>

static void C_bincount(double *x, R_xlen_t n, double *breaks, R_xlen_t nb, int *count, int right, int include_border) {
  R_xlen_t i, lo, hi, nb1 = nb - 1, new;

  memset(count, 0, nb1 * sizeof(int));
  for (i = 0; i < n; i++) {
    lo = 0;
    hi = nb1;
    if (breaks[lo] <= x[i] && (x[i] < breaks[hi] || (x[i] == breaks[hi] && include_border))) {
      while (hi - lo >= 2) {
        new = (hi + lo) / 2;
        if (x[i] > breaks[new] || (!right && x[i] == breaks[new])) {
          lo = new;
        } else {
          hi = new;
        }
      }
      count[lo]++;
    }
  }
}
SEXP C_BinCount(SEXP x, SEXP breaks, SEXP right, SEXP lowest) {
  x = PROTECT(coerceVector(x, REALSXP));
  breaks = PROTECT(coerceVector(breaks, REALSXP));
  R_xlen_t n = XLENGTH(x), nB = XLENGTH(breaks);
  int sr = asLogical(right), sl = asLogical(lowest);
  if (sr == NA_INTEGER) {
    error(("invalid '%s' argument"), "right");
  }
  if (sl == NA_INTEGER) {
    error(("invalid '%s' argument"), "include.lowest");
  }
  SEXP counts = PROTECT(allocVector(INTSXP, nB - 1));
  C_bincount(REAL(x), n, REAL(breaks), nB, INTEGER(counts), sr, sl);
  UNPROTECT(3);
  return counts;
}

The sliced result

static void C_bincount(double *x, R_xlen_t n, double *breaks, R_xlen_t nb, int *count, int right, int include_border) {
  for (i = 0; i < n; i++) {
    lo = 0;
    if (breaks[lo] <= x[i] && (x[i] < breaks[hi] || (x[i] == breaks[hi] && include_border))) {
      while (hi - lo >= 2) {
        new = (hi + lo) / 2;
        if (x[i] > breaks[new] || (!right && x[i] == breaks[new])) {
          lo = new;
        } else {
          hi = new;
        }
      }
      count[lo]++;
    }
  }
}
SEXP C_BinCount(SEXP x, SEXP breaks, SEXP right, SEXP lowest) {
  x = PROTECT(coerceVector(x, REALSXP));
  breaks = PROTECT(coerceVector(breaks, REALSXP));
  R_xlen_t n = XLENGTH(x), nB = XLENGTH(breaks);
  int sr = asLogical(right), sl = asLogical(lowest);
  if (sr == NA_INTEGER) {
    error(("invalid '%s' argument"), "right");
  }
  if (sl == NA_INTEGER) {
    error(("invalid '%s' argument"), "include.lowest");
  }
  C_bincount(REAL(x), n, REAL(breaks), nB, INTEGER(counts), sr, sl);
  UNPROTECT(3);
}

The declaration is missing , is this normal to get the sliced one with no declaration ?
And what if I need both forward and backward slice , what arguments should I use ?

@mchalupa
Copy link
Owner

mchalupa commented Oct 6, 2021

And is the declaration present if you skip slicing? That is, just compile the code to LLVM and then (without slicing) use your tool to generate the source code?

@mchalupa
Copy link
Owner

mchalupa commented Oct 6, 2021

And what if I need both forward and backward slice , what arguments should I use ?

The forward slice in DG does backward slicing to make the slice executable, is that what you want?

@Moriarty002
Copy link
Author

And is the declaration present if you skip slicing? That is, just compile the code to LLVM and then (without slicing) use your tool to generate the source code?

Yes , I use llvm-to-source tmp.bc tmp.c , it still has declaration
but when I use llvm-to-source tmp.sbc tmp.c , it has no declaration

@mchalupa
Copy link
Owner

mchalupa commented Oct 15, 2021

Oh, I thought that the output was from your clang-based tool. If the output is from the llvm-to-source, then it is normal that there are no declarations. llvm-to-source does not generate executable code, it is just a debugging tool.

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