描述
移除层级中作为独立实体的函数。完成内联后,函数将消隐到调用函数内,不再显示为 RTL 中的层级的独立层次。
重要: 内联函数时也会将应用于该函数的所有编译指示或指令消隐掉。在 Vitis HLS 中,忽略应用于内联函数的任意编译指示或指令。
在某些情况下,将函数内联即可使函数内的运算以更有效的方式与调用函数进行共享和优化。但内联函数无法共享或复用,因此如果父函数多次调用内联函数,则可能导致增加 RTL 实现所需的面积。
根据指定 INLINE 编译指示的方式,该编译指示应用到的范围与定义该编译指示的范围会有所不同:
-
INLINE
- 如不指定实参,那么该编译指示表示,指定该编译指示的函数应向上内联到任意调用函数内。
-
INLINE off
- 该编译指示表示,指定该编译指示的函数不应向上内联到任意调用函数内。这表示禁用特定函数的内联操作,此类特定函数原本可能自动内联或者在递归过程中内联。
-
INLINE recursive
- 表示将该编译指示应用于它分配到的函数体。它向下应用,以递归方式内联该函数的内容。
默认情况下,内联只能在函数层级的下一级上执行,而不能对子函数执行。但 recursive
选项允许您指定穿过层级的多个层次进行内联。
语法
将 C 语言源代码中的编译指示置于函数或代码区域的主体内。
#pragma HLS inline <recursive | off>
其中:
-
recursive
- 默认情况下,仅执行一级函数内联,并且不内联指定函数内部的函数。
recursive
选项会在指定函数或区域内按递归方式内联所有函数。 -
off
- 禁用函数内联以防止指定函数发生内联。例如,如果在函数中指定
recursive
,该选项会阻止调用的特定函数进行内联,同时所有其他函数均可进行内联。提示: Vitis HLS 工具会自动内联小型函数,并将 INLINE 编译指示与off
选项搭配使用以阻止此自动内联操作。
示例 1
以下示例用于对 func_top
主体内部的所有函数执行内联,以递归方式向下内联穿越整个函数层级,但 func_sub
函数不执行内联。递归编译指示置于 func_top
函数内。用于禁用内联的编译指示则置于 func_sub
函数内:
func_sub (p, q) {
#pragma HLS inline off
int q1 = q + 10;
func(p1,q);// foo_3
...
}
void func_top { a, b, c, d} {
#pragma HLS inline recursive
...
func(a,b);//func_1
func(a,c);//func_2
func_sub(a,d);
...
}
提示: 请注意,在此示例中,INLINE RECURSIVE 向下应用于
func_top
函数内容,但 INLINE OFF 则直接应用于 func_sub
。示例 2
此示例用于将 copy_output
函数内联到调用 copy_output
的任意函数或区域内。
void copy_output(int *out, int out_lcl[OSize * OSize], int output) {
#pragma HLS INLINE
// Calculate each work_item's result update location
int stride = output * OSize * OSize;
// Work_item updates output filter/image in DDR
writeOut: for(int itr = 0; itr < OSize * OSize; itr++) {
#pragma HLS PIPELINE
out[stride + itr] = out_lcl[itr];
}