..

Llvm_use

temp.cpp

int add(int p1,int p2) {
    int p3 = p1+p2;
    return p3;
}

cpp file -> AST

$ clang -Xclang -ast-dump ./temp.cpp
TranslationUnitDecl 0xf1b058 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0xf1b930 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0xf1b5f0 '__int128'
|-TypedefDecl 0xf1b9a0 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0xf1b610 'unsigned __int128'
|-TypedefDecl 0xf1bd18 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'
| `-RecordType 0xf1ba90 '__NSConstantString_tag'
|   `-CXXRecord 0xf1b9f8 '__NSConstantString_tag'
|-TypedefDecl 0xf1bdb0 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0xf1bd70 'char *'
|   `-BuiltinType 0xf1b0f0 'char'
|-TypedefDecl 0xf58de8 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'
| `-ConstantArrayType 0xf58d90 '__va_list_tag [1]' 1 
|   `-RecordType 0xf1bea0 '__va_list_tag'
|     `-CXXRecord 0xf1be08 '__va_list_tag'
`-FunctionDecl 0xf58fb0 <./temp.cpp:1:1, line:4:1> line:1:5 add 'int (int, int)'
  |-ParmVarDecl 0xf58e58 <col:9, col:13> col:13 used p1 'int'
  |-ParmVarDecl 0xf58ed8 <col:16, col:20> col:20 used p2 'int'
  `-CompoundStmt 0xf59218 <col:24, line:4:1>
    |-DeclStmt 0xf591b8 <line:2:5, col:19>
    | `-VarDecl 0xf590c0 <col:5, col:17> col:9 used p3 'int' cinit
    |   `-BinaryOperator 0xf59198 <col:14, col:17> 'int' '+'
    |     |-ImplicitCastExpr 0xf59168 <col:14> 'int' <LValueToRValue>
    |     | `-DeclRefExpr 0xf59128 <col:14> 'int' lvalue ParmVar 0xf58e58 'p1' 'int'
    |     `-ImplicitCastExpr 0xf59180 <col:17> 'int' <LValueToRValue>
    |       `-DeclRefExpr 0xf59148 <col:17> 'int' lvalue ParmVar 0xf58ed8 'p2' 'int'
    `-ReturnStmt 0xf59208 <line:3:5, col:12>
      `-ImplicitCastExpr 0xf591f0 <col:12> 'int' <LValueToRValue>
        `-DeclRefExpr 0xf591d0 <col:12> 'int' lvalue Var 0xf590c0 'p3' 'int'
$ # ......

ast format

TranslationUnitDecl <<invalid sloc>> <invalid sloc>
|-TypedefDecl <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType '__int128'
|-TypedefDecl <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 'unsigned __int128'
|-TypedefDecl <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'
| `-RecordType 0xf1ba90 '__NSConstantString_tag'
|   `-CXXRecord 0xf1b9f8 '__NSConstantString_tag'
|-TypedefDecl <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 'char *'
|   `-BuiltinType 0xf1b0f0 'char'
|-TypedefDecl <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'
| `-ConstantArrayType '__va_list_tag [1]' 1 
|   `-RecordType '__va_list_tag'
|     `-CXXRecord '__va_list_tag'
`-FunctionDecl add 'int (int, int)'
  |-ParmVarDecl used p1 'int'
  |-ParmVarDecl used p2 'int'
  `-CompoundStmt
    |-DeclStmt
    | `-VarDecl used p3 'int' cinit
    |   `-BinaryOperator 'int' '+'
    |     |-ImplicitCastExpr 'int' <LValueToRValue>
    |     | `-DeclRefExpr 'int' lvalue ParmVar 'p1' 'int'
    |     `-ImplicitCastExpr 'int' <LValueToRValue>
    |       `-DeclRefExpr 'int' lvalue ParmVar 'p2' 'int'
    `-ReturnStmt
      `-ImplicitCastExpr 'int' <LValueToRValue>
        `-DeclRefExpr 'int' lvalue Var 'p3' 'int'

cpp file -> IR

$ clang++ -S -emit-llvm -o temp.ir temp.cpp

temp.ir

; ModuleID = 'temp.cpp'
source_filename = "temp.cpp"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @_Z3addii(i32 %0, i32 %1) #0 {
  %3 = alloca i32, align 4
  %4 = alloca i32, align 4
  %5 = alloca i32, align 4
  store i32 %0, i32* %3, align 4
  store i32 %1, i32* %4, align 4
  %6 = load i32, i32* %3, align 4
  %7 = load i32, i32* %4, align 4
  %8 = add nsw i32 %6, %7
  store i32 %8, i32* %5, align 4
  %9 = load i32, i32* %5, align 4
  ret i32 %9
}

attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 10.0.0-4ubuntu1 "}

这段IR代码是一个简单的C++函数的LLVM IR表示。这个函数被命名为_Z3addii,接受两个整数参数并返回一个整数。以下是对IR代码的分析:

  1. ModuleIDsource_filename:这些行提供了模块的标识信息,指明了IR的来源文件和数据布局。
  2. target datalayouttarget triple:这些行定义了目标平台的数据布局和三元组(target triple)。这些信息有助于确保生成的IR代码与目标平台兼容。
  3. 函数定义:IR代码中的主要部分是函数定义,使用define关键字。函数名是_Z3addii,它接受两个i32类型(32位整数)的参数,分别为%0%1
  4. 局部变量:在函数内部,您可以看到使用alloca指令来分配内存空间用于三个整数局部变量,分别为%3%4%5。这些局部变量用于存储函数参数和计算结果。
  5. storeload 指令:使用store指令将参数值存储到相应的局部变量中,然后使用load指令从局部变量中加载值。
  6. add 指令:使用add指令执行整数相加操作,将%6%7相加的结果存储在%8中。
  7. ret 指令:最后,使用ret指令返回整数值,它的值来自%9,即相加的结果。
  8. attributes:这个部分提供了有关函数的属性信息,如noinlinenounwindoptnone等。这些属性指定了函数的行为和编译器的优化选项。
  9. !llvm.module.flags!llvm.ident:这些是LLVM模块级别的元数据,包括编译器版本和其他相关信息。

总之,这段IR代码表示一个C++函数,该函数接受两个整数参数,将它们相加,并返回结果。这只是一个简单的示例,但LLVM IR可以表示复杂的程序和函数,供编译器进行进一步的优化和代码生成。