新闻中心

EEPW首页>嵌入式系统>设计应用> 高效的C编程之: 函数调用

高效的C编程之: 函数调用

作者: 时间:2013-09-30 来源:网络 收藏

本文引用地址://m.amcfsurvey.com/article/257016.htm

14.9.4嵌套优化

注意

嵌套优化(Tail-Calloptimization)只适用于armcc。编译时如果使用-g或-debug选项,编译器自动关闭该功能。

一个函数如果在其结束时调用了另一个函数,则编译器使用B指令调转到被调用函数,而非BL指令。这样就避免了一级不必要的函数返回。图14.3显示了嵌套优化的调用过程。

图14.3嵌套优化过程

当编译时使用-O1或-O2选项时,编译器都执行这种嵌套优化。需要注意的是,当函数中引用了局部变量地址,由于指针别名问题的影响,即使函数在返回时调用了其他函数,编译器也不会使用嵌套优化。

下面通过一个例子来分析嵌套优化是如何提高代码执行效率的。

externintfunc2(int);

intfunc1(inta,intb)

{if(a>b)

return(func2(a-b));

else

return(func2(b-a));

}

编译后的代码如下所示。

func1

CMPa1,a2

SUBLEa1,a2,a1

SUBGTa1,a1,a2

Bfunc2

首先,func1中使用B指令代替BL指令,不用担心lr寄存器被破坏,减少了对寄存器压栈保护操作。另外,程序直接从func2返回到调用func1的函数,减少一次函数返回。如果说正常的指令调用过程为:

BL+BL+MOVpc,lr+MOVpc,lr

那么经过嵌套优化的过程就可以表示为:

BL+BL+MOVpc,lr

这样,总的开销将减少25%。

14.9.5单纯子函数

所谓单纯子函数(PureFunctions)是指那些函数返回值只和调用参数有关。换句话说,就是如果调用函数的参数相同,那么函数的返回结果也相同。如果程序中存在这样的函数,可以在函数定义时使用_pure进行声明,这样在程序编译时编译器会根据函数的调用情况对其进行优化。

下面的例子显示了当函数用_pure声明时,编译器对其所做的优化。

程序源码文件如下。

intsquare(intx)

{

returnx*x;

}

intf(intn)

{

returnsquare(n)+square(n)

}

编译后的结果如下。

square

MOVa2,a1

MULa1,a2,a2

MOVpc,lr

f

STMDBsp!,{lr}

MOVa3,a1

BLsquare

MOVa4,a1

MOVa1,a3

BLsquare

ADDa1,a4,a1

LDMIAsp!,{pc}

上面的程序中,square函数为“单纯子函数”,当使用_pure声明该函数时编译器在调用该函数时,将对程序进行优化。

声明的方法和编译后的结果如下所示。

__pureintsquare(intx)

{

returnx*x;

}

f

STMDBsp!,{lr}

BLsquare

MOVa1,a1,LSL#1

LDMIAsp!,{pc}

从编译后的代码中可以看到,用_pure声明的函数在f函数中只调用了一次。

虽然“单纯子函数”可以提高代码执行效率,但同时也会带来一些负面影响。比如,在“单纯子函数”中,不能直接或间接访问内存地址。所以在程序中使用“单纯子函数”时要特别小心。

另外,还可以使用#pragma声明“单纯子函数”,下面的代码显示了它的声明过程。

#pragmano_side_effects

/*functiondefinition*/

#pragmaside_effects



评论


相关推荐

技术专区

关闭