..
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代码的分析:
ModuleID
和source_filename
:这些行提供了模块的标识信息,指明了IR的来源文件和数据布局。target datalayout
和target triple
:这些行定义了目标平台的数据布局和三元组(target triple)。这些信息有助于确保生成的IR代码与目标平台兼容。- 函数定义:IR代码中的主要部分是函数定义,使用
define
关键字。函数名是_Z3addii
,它接受两个i32
类型(32位整数)的参数,分别为%0
和%1
。 - 局部变量:在函数内部,您可以看到使用
alloca
指令来分配内存空间用于三个整数局部变量,分别为%3
、%4
和%5
。这些局部变量用于存储函数参数和计算结果。 store
和load
指令:使用store
指令将参数值存储到相应的局部变量中,然后使用load
指令从局部变量中加载值。add
指令:使用add
指令执行整数相加操作,将%6
和%7
相加的结果存储在%8
中。ret
指令:最后,使用ret
指令返回整数值,它的值来自%9
,即相加的结果。attributes
:这个部分提供了有关函数的属性信息,如noinline
、nounwind
、optnone
等。这些属性指定了函数的行为和编译器的优化选项。!llvm.module.flags
和!llvm.ident
:这些是LLVM模块级别的元数据,包括编译器版本和其他相关信息。
总之,这段IR代码表示一个C++函数,该函数接受两个整数参数,将它们相加,并返回结果。这只是一个简单的示例,但LLVM IR可以表示复杂的程序和函数,供编译器进行进一步的优化和代码生成。