dg icon indicating copy to clipboard operation
dg copied to clipboard

Dose this tool can do parameter slice

Open Moriarty002 opened this issue 4 years ago • 8 comments

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

Moriarty002 avatar May 11 '21 11:05 Moriarty002

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

mchalupa avatar May 11 '21 13:05 mchalupa

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 .

Moriarty002 avatar May 11 '21 14:05 Moriarty002

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.

mchalupa avatar May 11 '21 19:05 mchalupa

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 ?

Moriarty002 avatar Sep 27 '21 02:09 Moriarty002

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 avatar Oct 06 '21 16:10 mchalupa

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?

mchalupa avatar Oct 06 '21 16:10 mchalupa

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

Moriarty002 avatar Oct 15 '21 03:10 Moriarty002

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.

mchalupa avatar Oct 15 '21 05:10 mchalupa