基于LLVM的Pass优化

匿名 (未验证) 提交于 2019-12-03 00:39:02

当我们如果完成了对源码的转换,得到了LLVM的IR表示形式,它是作为一种向汇编代码转换的一个公共平台,依赖不同的后端会得到不同的汇编码,在转换为汇编码之前,如果我们对IR进行优化的话就可以得到执行效率更高的代码

在LLVM的架构当中,Pass的作用就是优化LLVM IR,Pass作用于LLVM IR,用来处理IR,分析IR,寻找优化的机会并修改IR,从而产生优化的代码。在下面命令行工具opt就是用来在LLVM IR上运行各种优化Pass的

通常来说编译器的优化会有多种级别,有0~3级别,优化级别越高,代码得到的优化也越多

首先我们先去写一个C语言程序

int main(int argc,char **argv) {     int i,j,k,t=0;     for (i=0; i<10; i++) {         for (j=0; j<10; j++) {             for (k=0; k<10; k++) {                 t++;             }         }          for (j=0;j<10; j++) {             t++;         }      }      for (i=0; i<20; i++) {         for (j=0; j<20; j++) {             t++;         }          for (j=0; j<20; j++) {             t++;         }     }     return t; }

使用clang命令也就是clang -S -O0 -emit-llvm example.c 把源码转换成LLVM IR生成的包含LLVM IR的example.ll的文件内容如下所示

; ModuleID = 'example.c' source_filename = "example.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.13.0"  ; Function Attrs: noinline nounwind optnone ssp uwtable define i32 @main(i32, i8**) #0 {   %3 = alloca i32, align 4   %4 = alloca i32, align 4   %5 = alloca i8**, align 8   %6 = alloca i32, align 4   %7 = alloca i32, align 4   %8 = alloca i32, align 4   %9 = alloca i32, align 4   store i32 0, i32* %3, align 4   store i32 %0, i32* %4, align 4   store i8** %1, i8*** %5, align 8   store i32 0, i32* %9, align 4   store i32 0, i32* %6, align 4   br label %10  ; <label>:10:                                     ; preds = %42, %2   %11 = load i32, i32* %6, align 4   %12 = icmp slt i32 %11, 10   br i1 %12, label %13, label %45  ; <label>:13:                                     ; preds = %10   store i32 0, i32* %7, align 4   br label %14  ; <label>:14:                                     ; preds = %28, %13   %15 = load i32, i32* %7, align 4   %16 = icmp slt i32 %15, 10   br i1 %16, label %17, label %31  ; <label>:17:                                     ; preds = %14   store i32 0, i32* %8, align 4   br label %18  ; <label>:18:                                     ; preds = %24, %17   %19 = load i32, i32* %8, align 4   %20 = icmp slt i32 %19, 10   br i1 %20, label %21, label %27  ; <label>:21:                                     ; preds = %18   %22 = load i32, i32* %9, align 4   %23 = add nsw i32 %22, 1   store i32 %23, i32* %9, align 4   br label %24  ; <label>:24:                                     ; preds = %21   %25 = load i32, i32* %8, align 4   %26 = add nsw i32 %25, 1   store i32 %26, i32* %8, align 4   br label %18  ; <label>:27:                                     ; preds = %18   br label %28  ; <label>:28:                                     ; preds = %27   %29 = load i32, i32* %7, align 4   %30 = add nsw i32 %29, 1   store i32 %30, i32* %7, align 4   br label %14  ; <label>:31:                                     ; preds = %14   store i32 0, i32* %7, align 4   br label %32  ; <label>:32:                                     ; preds = %38, %31   %33 = load i32, i32* %7, align 4   %34 = icmp slt i32 %33, 10   br i1 %34, label %35, label %41  ; <label>:35:                                     ; preds = %32   %36 = load i32, i32* %9, align 4   %37 = add nsw i32 %36, 1   store i32 %37, i32* %9, align 4   br label %38  ; <label>:38:                                     ; preds = %35   %39 = load i32, i32* %7, align 4   %40 = add nsw i32 %39, 1   store i32 %40, i32* %7, align 4   br label %32  ; <label>:41:                                     ; preds = %32   br label %42  ; <label>:42:                                     ; preds = %41   %43 = load i32, i32* %6, align 4   %44 = add nsw i32 %43, 1   store i32 %44, i32* %6, align 4   br label %10  ; <label>:45:                                     ; preds = %10   store i32 0, i32* %6, align 4   br label %46  ; <label>:46:                                     ; preds = %70, %45   %47 = load i32, i32* %6, align 4   %48 = icmp slt i32 %47, 20   br i1 %48, label %49, label %73  ; <label>:49:                                     ; preds = %46   store i32 0, i32* %7, align 4   br label %50  ; <label>:50:                                     ; preds = %56, %49   %51 = load i32, i32* %7, align 4   %52 = icmp slt i32 %51, 20   br i1 %52, label %53, label %59  ; <label>:53:                                     ; preds = %50   %54 = load i32, i32* %9, align 4   %55 = add nsw i32 %54, 1   store i32 %55, i32* %9, align 4   br label %56  ; <label>:56:                                     ; preds = %53   %57 = load i32, i32* %7, align 4   %58 = add nsw i32 %57, 1   store i32 %58, i32* %7, align 4   br label %50  ; <label>:59:                                     ; preds = %50   store i32 0, i32* %7, align 4   br label %60  ; <label>:60:                                     ; preds = %66, %59   %61 = load i32, i32* %7, align 4   %62 = icmp slt i32 %61, 20   br i1 %62, label %63, label %69  ; <label>:63:                                     ; preds = %60   %64 = load i32, i32* %9, align 4   %65 = add nsw i32 %64, 1   store i32 %65, i32* %9, align 4   br label %66  ; <label>:66:                                     ; preds = %63   %67 = load i32, i32* %7, align 4   %68 = add nsw i32 %67, 1   store i32 %68, i32* %7, align 4   br label %60  ; <label>:69:                                     ; preds = %60   br label %70  ; <label>:70:                                     ; preds = %69   %71 = load i32, i32* %6, align 4   %72 = add nsw i32 %71, 1   store i32 %72, i32* %6, align 4   br label %46  ; <label>:73:                                     ; preds = %46   %74 = load i32, i32* %9, align 4   ret i32 %74 }

我们可以使用opt -O0 -S example.ll去进行优化包含IR的example.ll文件,我们还可以使用下面的命令进行优化

  • opt -O1 -S example.ll
  • opt -O2 -S example.ll
  • opt -O3 -S example.ll

我们通过执行opt -O1 -S example.ll获得的结果如下所示,优化的直接返回1900了,其实上面的C程序返回的结果就是1900

; ModuleID = 'example.ll' source_filename = "example.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.13.0"  ; Function Attrs: norecurse nounwind readnone define i32 @main(i32, i8** nocapture readnone) local_unnamed_addr #0 {   ret i32 1900 }  attributes #0 = { norecurse nounwind readnone }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!