栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

llvm libLLVMCore源码分析 20 - Function Class

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

llvm libLLVMCore源码分析 20 - Function Class

源码路径

llvmincludellvmIRFunction.h

llvm Function class

在llvm中,使用Function class表示函数,Function class的定义如下:

class Function : public GlobalObject, public ilist_node {
...
};

首先,Function继承自GlobalObject,是一个全局独立对象。

其次,Function继承ilist_node,主要的作用是:通过当前节点(Function),遍历链表上其他节点(Function)。遍历Module中的Function:

Module *M = ...;
for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) {
    Function &F = *I;
    ...
}
Function Declaration & definition

Function声明的语法如下:

declare [linkage] [visibility] [DLLStorageClass]
        [cconv] [ret attrs]
         @ ([argument list])
        [(unnamed_addr|local_unnamed_addr)] [AddrSpace] 
        [partition "name"] [align N]
        [gc] [prefix Constant] [prologue Constant]

Function定义的语法如下:

define [linkage] [PreemptionSpecifier] [visibility] [DLLStorageClass]
       [cconv] [ret attrs]
        @ ([argument list])
       [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [fn Attrs]
       [section "name"] [partition "name"] [comdat [($name)]] [align N]
       [gc] [prefix Constant] [prologue Constant] [personality Constant]
       (!name !N)* { ... }
linkage & visibility​​​

参考llvm libLLVMCore源码分析 19 - GlobalValue

DLLStorageClass

WINDOWS相关,暂不分析。

cconv

参考llvm libLLVMCore源码分析 13 - Other Operators

unnamed_addr|local_unnamed_addr

unnamed_addr:函数的地址不重要,只需要关心函数的内容,这样相同的函数满足一定条件就可以合并。

local_unnamed_addr:函数的地址在当前的Module内不重要,只需要关心函数的内容,这样Module内相同的函数满足一定条件就可以合并。

fn Attrs

Function Attributes是函数的一部分,相同的函数类型,可以有不同的Attributes,如下所示:

define void @f() noinline { ... }
define void @f() alwaysinline { ... }
define void @f() alwaysinline optsize { ... }
define void @f() optsize { ... }

可选的Function Attributes如下:

alignstack():按照n对齐栈帧。

allocsize([, ]):函数总是返回指针指向的给定长度的内存。

alwaysinline:inliner忽略inlining size的阈值,尽可能进行inline。

builtin:函数是builtin function。

cold:函数不经常被调用。

convergent:表明调用该函数不能在控制流上依赖额外的值。例如 llvm.nvvm.barrier0就有convergent属性,主要用于SIMD/SIMT架构下。

disable_sanitizer_instrumentation:禁止Sanitizer插桩。

dontcall-error:当函数调用没有被优化掉时,会上报error。

dontcall-warn:当函数调用没有被优化掉时,会上报warning。

frame-pointer:指示函数是否需要保存栈帧指针,none:不需要。non-leaf:函数调用其他函数时需要。all:全都需要。

hot:函数经常被调用。

inaccessiblememonly:函数只能访问Module内其他函数不访问的内存。

inaccessiblemem_or_argmemonly:函数只能访问Module内其他函数不访问的内存,或指针参数传递的内存。

inlinehint:建议inliner进行inline,类似C中的inline关键字。

jumptable:函数会被加到jump-instruction table,所有对函数地址的引用会被替换为jump-instruction table中的指针,所以函数必须是unnamed_addr。

minsize:指示编译器尽可能减小函数的codesize。

naked:禁止生产prologue / epilogue。

no-inline-line-tables:inline函数的时候用call site的源码位置替换函数的源码位置。

no-jump-tables:禁止switch case生产jump table。

nobuiltin:函数不是builtin function。

noduplicate:不能在一个函数内多处调用。

nofree:函数不调用内存释放函数。

noimplicitfloat:禁止隐式浮点代码。

noinline:只是inliner禁止inline当前函数。

nomerge:禁止合并函数调用(比如尾调用优化)

nonlazybind:禁止函数进行lazy symbol binding。

noprofile:禁止profiling插桩。

noredzone:禁止生成redzone。

indirect-tls-seg-refs:禁止通过segment register使用TLS。

noreturn:函数不通过return指令返回。

norecurse:函数不直接或间接递归调用自己。

willreturn:调用函数要么产生未定义行为,要么会返回到调用栈中的某一个点执行。

nosync:函数不和其他线程通过内存或其他方式同步。

nounwind:函数不抛出异常。

nosanitize_bounds:禁止Sanitizer进行边界检查插桩。

nosanitize_coverage:禁止SanitizerCoverage插桩。

null_pointer_is_valid:null地址是合法地址。

optforfuzzing:只是函数向最大化fuzzing signal的方向优化。

optnone:禁止除了过程间优化pass之外的优化。

optsize:在对性能影响不大的前提下,尽量优化函数的codesize。

patchable-function:函数必须遵循一些约定,保证可以被打补丁。

probe-stack:生成一个guard region在栈的结尾。

readnone:函数仅用参数计算结果,而不解引用参数指针,或者访问可变的状态。并且函数不能改写调用方可见的任何内存和状态。

readonly:函数不能改写调用方可见的任何内存和状态。

stack-probe-size:函数不能使用超过stack-probe-size指定大小的栈空间。

no-stack-arg-probe:禁止stack probe。

writeonly:函数只会写内存。

argmemonly:函数只能访问指针参数传递的内存。

returns_twice:函数可以返回两次,比如C中的setjmp。

safestack:使能SafeStack保护。

sanitize_address:使能AddressSanitizer 。

sanitize_memory:使能MemorySanitizer 。

sanitize_thread:使能ThreadSanitizer 。

sanitize_hwaddress:使能HWAddressSanitizer。

sanitize_memtag:使能MemTagSanitizer

speculative_load_hardening:只能Speculative load hardening。

speculatable:函数除了计算结果之外没有副作用,不存在未定义行为。

ssp:使能栈保护:1)char数组超过ssp-buffer-size;2)符合类型包含char数组超过ssp-buffer-size;3)alloca申请的变量或者常量超过ssp-buffer-size

sspstrong:使能栈保护:1)所有的数组;2)所有的包含数组的复合类型;3)alloca;4)被取地址的局部变量。

sspreq:使能栈保护:所有场景。.

strictfp:指示函数需要严格的浮点语义。

denormal-fp-math:指示浮点数如何处理小值。

denormal-fp-math-f32:和denormal-fp-math语义相同,但仅对32bit的浮点类型生效。

thunk:指示函数通过尾调用代理其他函数。

tls-load-hoist:函数通过TLS变量减少冗余的TLS地址计算。

uwtable[(sync|async)]:为函数生成unwind table entry。

nocf_check:指示不需要控制流检查。

shadowcallstack:使能ShadowCallStack检查。

mustprogress:指示函数会通过返回或栈展开等方式和环境交互。

warn-stack-size=:栈帧大小超过threshold后上报warning。

vscale_range([, ]):设置vscale的上下限。

param attr & ret attrs

Parameter Attributes是函数参数和返回值的属性,示例如下所示:

declare i32 @printf(i8* noalias nocapture, ...)
declare i32 @atoi(i8 zeroext)
declare signext i8 @returns_signed_char()

可选的Parameter Attributes如下:

zeroext:零扩展。

signext:符号位扩展。

inreg:以目标架构特定的方式处理(通常是放到寄存器而不是内存中)。

byval():指针参数按值传递,参数再caller和callee之间被隐式拷贝。

byref():指针参数按引用传递。

preallocated():指针参数按值传递,参数由call指令分配内存并初始化。

inalloca():允许caller取栈变量的地址进行传参,主要是为了支持Microsoft C++ ABI。

sret():指针参数是指向结构体的指针,是父函数的返回值。

elementtype():只能被用于intrinsic的指针参数,语义和具体的intrinsic相关。

align  or align():指针或者指针矢量地址按照n对齐。

noalias:函数只能通过这个指针参数或返回值去访问这片内存,用在指针参数上和C99中的restrict语义相同,用在返回值上,既函数的返回值和调用方的任何对象的内存都不相交。

nocapture:函数不能捕获这个指针参数。

nofree:函数不能free这个指针参数

nest:指示指针参数可以通过trampoline intrinsics去除,该属性用于支持C语言中的嵌套函数。

returned:指示函数总是将这个参数作为返回值。

nonnull:指针参数不为null。

dereferenceable():指针参数可以被解引用,n代表可以解引用的bytes。

dereferenceable_or_null():指针参数要么为空,要么可以被解引用,n代表可以解引用的bytes。

swiftself:指示这个参数是swift中的self/context。

swiftasync:指示这个参数是swift中的asynchronous context。

swifterror:用于优化swift的错误处理。

immarg:参数是一个立即数,是一个平凡的整形或者浮点常量。

noundef:参数或者返回值不是undef的。

alignstack():指示后端在栈帧上分配参数时要考虑对齐。

allocalign:这个参数是函数申请的内存返回值的对齐。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/767529.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号