What are the glue and chain dependencies in DAG LLVM?

I am a little new to LLVM and compilers.

I decided to create a DAG using the following command

llc -view-sched-dags hello_world.ll 

I have a really big chart with different types of dependencies. "Getting Started with Basic LLVM Libraries" explains that:

Black arrows indicate data flow dependency.
Red arrows indicate glue addiction
Blue dotted arrows indicate chain addiction.

I clearly remember talking about data flow dependencies in my compiler class at school. But I donโ€™t remember talking about the other two. Can someone explain the meaning of the other dependencies? Any help is appreciated.

hello_world.cpp

 #include <stdio.h> #include <assert.h> int sum(int a, int b) { return a + b; } int main(int argc, char** argv) { printf("Hello World! %d\n", sum(argc, 1)); return 0; } 

hello_world.ll

 ; ModuleID = 'hello_world.cpp' target datalayout = "em:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [17 x i8] c"Hello World! %d\0A\00", align 1 ; Function Attrs: nounwind uwtable define i32 @_Z3sumii(i32 %a, i32 %b) #0 { entry: %a.addr = alloca i32, align 4 %b.addr = alloca i32, align 4 store i32 %a, i32* %a.addr, align 4 store i32 %b, i32* %b.addr, align 4 %0 = load i32* %a.addr, align 4 %1 = load i32* %b.addr, align 4 %add = add nsw i32 %0, %1 ret i32 %add } ; Function Attrs: uwtable define i32 @main(i32 %argc, i8** %argv) #1 { entry: %retval = alloca i32, align 4 %argc.addr = alloca i32, align 4 %argv.addr = alloca i8**, align 8 store i32 0, i32* %retval store i32 %argc, i32* %argc.addr, align 4 store i8** %argv, i8*** %argv.addr, align 8 %0 = load i32* %argc.addr, align 4 %call = call i32 @_Z3sumii(i32 %0, i32 1) %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i32 0, i32 0), i32 %call) ret i32 0 } declare i32 @printf(i8*, ...) #2 attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.ident = !{!0} !0 = metadata !{metadata !"clang version 3.5.0 "} 

hello_world.main.jpg hello_world.main.jpg

hello_world.sum.jpg hello_world.sum.jpg

+6
source share
1 answer

The dependencies of the chains exclude the possibility that nodes with side effects (including memory operations and operations with an explicit register) will not be ordered relative to each other.

Adhesive prevents the breakdown of two nodes during planning. It is actually more subtle than this [1], but most of the time you do not need to worry about it. (If you are implementing your own backend that requires the two instructions to be adjacent to each other, you really want to use the pseudo-instruction instead and extend it after planning is done.)

[1]: see http://lists.llvm.org/pipermail/llvm-dev/2014-June/074046.html , for example

+7
source

All Articles