Reputation: 487
It seems LLVM can now emit DDGs for each loop in a function (https://github.com/llvm/llvm-project/blob/llvmorg-12.0.1/llvm/lib/Analysis/DDGPrinter.cpp).
I am able to generate CFG and Callgraph with opt --dot-cfg foo.bc
and with opt --dot-callgraph foo.bc
, but the similar opt --dot-ddg-only foo.bc
executes but generates no .dot
file. I also tried opt -passes=dot-ddg foo.bc
without success.
Is there another opt
possible call? Or someone has suggestions for other similar tools?
C code used (foo.bc
obtained with clang -c -emit-llvm foo.c -o foo.bc
):
void foo(int b[], int c[], int n){
for (int i = 1; i < n; i++) {
b[i] = c[i] + b[i-1];
}
}
int main(){
int b[] = {1, 2, 3, 4, 5};
int c[] = {1, 1, 1, 1, 1};
foo(b, c, 5);
}
Upvotes: 2
Views: 1823
Reputation: 303
My answer is probably naive as i am not an expert. I came across the same problem and found out this. First i compile your program to a readable IR:
clang -c -S -emit-llvm foo.c -o foo.ll
. Notice this is equivalent to a O0 optimisation level.
the -debug-pass-manager
option has been key to me to understand why nothing was neither printed nor written out. Call
% opt foo.ll -passes=dot-ddg -debug-pass-manager
(Note: this is using the new pass manager syntax) I noticed in the output, things like:
Skipping pass DDGDotPrinterPass on foo due to optnone attribute
Edit the IR foo.ll
and indeed, we can spot the optnone
attribute, e.g:
; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @foo(i32* noundef %b, i32* noundef %c, i32 noundef %n) #0 {
You can disable this attribute. I regenerate the IR with the proper option -disable-O0-optnone
% clang -O0 -Xclang -disable-O0-optnone foo.c -emit-llvm -S -o foo.ll
and now the attribute is gone :
; Function Attrs: noinline nounwind uwtable
define dso_local void @foo(i32* noundef %b, i32* noundef %c, i32 noundef %n) #0 {
This time the pass will take effect:
% opt foo.ll -disable-output -passes=dot-ddg
Writing 'ddg.foo.for.cond.dot'
Upvotes: 4