This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器:负数比较不会生成代码

Guru**** 2589280 points
Other Parts Discussed in Thread: MSP430FR5969

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/649197/compiler-negative-number-comparison-does-not-generate-code

主题中讨论的其他器件:MSP430FR5969

工具/软件:TI C/C++编译器

考虑这个简短测试代码。 问题是这种有符号32位数字比较  

if (<tempmin){ return total; }

不会生成任何汇编器代码、它始终跳至返回。 为什么?

#include 
#include 

#define short int16_t
#define long int32_t
#define USHORT uint16_t

short Temp_integral (short total、USHORT 值、USHORT 设定值、USHORT max);

/**
* main.c
*/
int main (void)
{
WDTCTL = WDTPW | WDTHOLD;//看门狗停止计时器
temp_integral (0、4096、410、32);
return 0;
}

#pragma FUNC_CANNOT_INLINE (Temp_Integral)

short Temp_integral (短整型总计、USHORT 值、USHORT 设定点、USHORT 最大值){
long volatile tempmin=-0x7FFE;
长挥发泡沫;
long volatile diff = 0;
/*
*负翻转检查
*
if (((long) value-setpoint)<tempmin){
退货总数;
}
DIFF=(长)值-(长)设定点;
foo=total+diff;
if (foo 最大值){
最大返回值;
}
返回总计+差异;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请将编译器版本(而不是 CCS)以及编译器看到的编译选项完全显示在这里。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    pfft、忘记了附件。

    -vmspx --data_model=restricted --use_hw_mpy=F5 --include_path="C:/ti/ccsv7/ccs_base/msp430/include --include_path="C:/Users/olli.mannisto/workspace_v7/testi --include_path="C:/ti/ccsv7/tools/compiler/ti-cgt-msp430_17.9.0.STS/include --advice:power=all --advice:hw_config=all --define=_MSP430FR5969_--include_path=C:--erratiag=us=us_support=unicon_support/capsilitsi-display=us_support=unicon_off-cp2=us_erratina-us_erratiag=u_cp2=us_off-us_erratia-us_erranag=us_support=un=us_off-up_erratina-display_support=us_guia-

    17.9.0.STS。  

    e2e.ti.com/.../main.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在此代码段中、由于整数字面量、IF 比较正在进行修整。 但是、我已经为使用变量的(修整)实际应用发送了代码。 但是,它也受到同样问题的影响。

    我尝试将函数的 USHORT 值参数更改为 USHORT 易失性值、因为 ADC 传感器读数实际上是易失性的。 没有影响。  

    在进一步的测试中、我发现将优化提升到1级会使比较工作、而0级不会生成任何代码。 这非常时髦。 遗憾的是、后续跟踪上升限制比较不会生成具有1级比较的代码。 一个清晰的错误案例、您是否同意?  

    这里是最新版本的代码、我在其中尝试消除任何不需要的有符号到无符号转换。 如果  

    if (((long) value-setpoint)<tempmin){
    退货总数;
    } 

    将后续行动注释掉比较(它是多余的)  

    if (<tempmin){
    退货总数;
    } 

    停止工作。  

    /*
    *计算温度积分、max 定义最大正值、因此
    我们在预热期间不会遇到*预热问题
    */
    
    Short Temp_integral (short volatile total、short volatile value、short Setpoint、short max){
    long volatile tempmin=-0x7FFE;
    长挥发泡沫;
    long volatile diff = 0;
    /*
    *负翻转检查
    * 
    /* if (((long) value-setpoint)<tempmin){ 退货总数; }
    * DIFF=(长)值-(长)设定点; foo=(long) total+(long) diff; if (foo (长)最大值){ 最大返回值; } 返回总计+差异; }

    我还意识到了  

    #pragma FUNC_CANNOT_INLINE (Temp_Integral)

    行需要在函数声明之前、以便它不会像实际函数之前那样产生影响。 但是、它对--opt_level 0或1没有影响。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    将优化设置为0可以解决此问题、但固件非常不可用。

    在深入了解了#pragma FUNCTION_OPTIONS 之后、我发现此行显然不执行任何操作:

    #pragma FUNCTION_OPTIONS (Temp_integral、"-opt_level=off")
    

    但是,*DID *给了我一个想法,我将 Temp_integral 函数拆分为它自己的文件,这样我就只能禁用该函数的优化。 这样代码就可以正常工作、而不会影响整个固件。 如果我看到了一个雪橇。 在代码中启用单个"if"语句。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您已经进行了几个更改构建选项和源代码的实验。  我决定在这一点上进行调查...

    [引用 user="Olli Mannisto"]在此代码段中、由于整数字面量、IF 比较正在进行修整。 但是、我已经为使用变量的(修整)实际应用发送了代码。 但它也受到同样的问题的影响。[/引述]

    我通过私人消息收到了该代码。  谢谢你。  我使用了您在该消息中发送的构建选项。  这些选项中包括将优化设置为0级。  然后、在后面的帖子中、您会指出使用优化级别0可以避免该问题。  因此、我将优化级别更改为3。   

    我无法运行代码、但仔细查看了汇编输出。  为此、我向编译中添加了-src_interlist 选项、然后检查生成的.asm 文件。  在本例中、仅检查使用--src_interlist 获得的优化器生成的注释非常有用。  有几种方法可以实现这一目的。 我做了这个...

    % type file.asm | perl -ne "print if m/^;\*[\*]/;"> cmts.txt 

    这使用 Perl 正则表达式来捕获优化器在 CMT.txt 文件中生成的注释。  正在检查该文件,我看到这个...

    ;* 18223-------------------- 如果(foo >= tempmin)转至 G4;
    ;;;;;*-------------------------- *
    ;****----------------------------------------------------------------------------------------------------- *
    ;****----------------------------------------------------------------------------------------------------- *;**
    -------------------- G3:
    ;* 18224---------------- 回返总额;
    ;*------------------------------------------------------ *;**
    -------------------- G4:
    

    下面的汇编代码看起来是正确的。  尽管我不得不承认我对 MSP430汇编的了解不够专业。  但是、有足够的时间来非常有信心进行这种比较。  随着比较的进行、这很简单。  编译器不太可能通过其自己的测试并出错。

    那么、这是我的猜测。  生成的汇编代码正确。  如果您运行完函数并完成、它会执行正确的操作。  但是、如果您在 CCS 中单步执行它、可能会出现问题。  在调试优化代码时、这种情况是可以预料的。  这有道理吗?

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这确实是一个有点复杂的报告。 总结我发现的内容:
    optimizion=off =>按预期工作
    optimization=0 =>如果比较已被优化、但结果确实符合预期
    optimization=1 =>与0相同、但显然有更多的代码正在执行
    优化=3 =>行为与1相同

    我希望0级优化不会彻底删除代码。 此外、#pragma FUNCTION_OPTIONS (Temp_integral、"-opt_level=off")似乎没有效果、这就是我将整型函数拆分为其自己的源文件的原因。 为了进行良好的测量、我还包含了#pragma FUNC_CANNOT_INLINE (Temp_integral)、但这也没有改变任何效果。

    为什么不能运行代码? MSP430FR5969评估板应该可以正常运行?

    我可以为您提供最新的代码、以便我们不会比较不同的内容。 我同时修复了一些错误、但它们不应该在这里产生影响。

    我以前遇到过类似的问题、固件检测信号 LED 闪烁例程处于更高的优化级别、这就是"发布"的优化级别为2而不是3的原因。 在这种情况下、您肯定可以验证是否跳过了代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    关于您所说的"如果比较已优化"、"彻底删除代码"或"正在跳过代码"等内容、请详细说明您要执行的操作。   

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    所有这些都意味着您在源代码中看到的不是您得到的结果。 在0级优化中、逐行调试跳过比较、您无法为其设置断点。 我认为"寄存器优化"不会发生这种情况?

    关于在优化3上被彻底跳过的代码、这意味着它在 tin 上所说的那样。 我的心跳 LED 根本不会在3级闪烁、因为代码根本没有执行。 在这种情况下、没有内联 pragma 恢复函数。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Olli Mannisto 说:
    在0级优化中、逐行调试跳过比较、您无法为其设置断点。

    对于--opt_level=0,这是不寻常的,但并不是完全的惊喜。

    [引用 user="Olli Mannisto"]由于代码根本没有执行、我的心跳 LED 指示灯根本不会在3级闪烁。

    我想详细了解一下这一点。  我可能已经有了代码。  但请记住、我每天都要处理多个问题。  因此、请耐心地告诉我、我需要使用哪些选项构建哪个文件来解决这个问题。  我还需要有关代码中要检查的函数的指导。   

    至于运行代码... 您可能不知道我支持所有 TI 编译器。  即使拥有运行每个测试用例所需的所有硬件、也是不切实际的。  这忽略了这样一个事实:大多数代码假定系统硬件的其余部分存在、提供它们的输入、接收输出等  在极少数情况下、我会运行客户代码。  但这远远不是典型的。  默认假设是、我必须在不运行任何内容的情况下解决问题。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    听起来您需要一些助理/团队成员。 也许 TI 会本着圣诞节的精神进行一些招聘。

    我发送给您的源实际上已对外部输入进行了修整、应该能够正常运行。 当我有一些空闲时间时、我将检查 LED 干扰、现在我正在对温度控制位进行微调。 代码比较广泛、因此如果问题暂时消失、我也不会感到意外。 固件在 opt=3时当然不能正常工作、但可能需要一些时间才能深入了解具体的故障位置。 代码现在位于25KB 标记处、我不知道嵌入式标准是否"庞大"、但它具有简单的合作多任务处理等大量功能