LLVM DAG中的“glue”和“chain”依赖是什么?

10

我对LLVM和编译器有些不熟悉。

我决定使用以下命令生成一个DAG

llc -view-sched-dags hello_world.ll

我有一个非常大的图,其中包含不同类型的依赖关系。《LLVM核心库入门》一书解释说:

黑色箭头表示数据流依赖
红色箭头表示粘合依赖
蓝色虚线箭头表示链式依赖

我清楚地记得在学校的编译器课程中讨论过数据流依赖。但我不记得讨论过其他两个依赖关系。有人可以解释一下其他依赖关系的含义吗?感谢任何帮助。

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;
}

你好_世界.ll

; ModuleID = 'hello_world.cpp'
target datalayout = "e-m: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 "}

你好_世界.主图.jpg 你好_世界.主图.jpg

你好_世界.汇总图.jpg 你好_世界.汇总图.jpg

1个回答

15

链式依赖性防止具有副作用(包括内存操作和显式寄存器操作)的节点相对于彼此被无序调度。

Glue可以防止两个节点在调度期间被分开。其实情况比这更微妙[1],但大多数时候你不需要担心它。(如果你正在实现需要两条指令相邻的自定义后端, 你真的想使用一个伪指令,然后在调度后进行扩展)

[1]: 参见 http://lists.llvm.org/pipermail/llvm-dev/2014-June/074046.html 的例子


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接