针对ARM A7故障的优化GCC输出
各位手臂装配专家注意 我有一些代码在优化时意外失败。我在一个简单的嵌入式设备单元测试中将其隔离。该代码是为ARM A7嵌入式环境构建的,使用gcc-ARM-8.3-2019.03-x86_64-ARM-eabi 该代码是一个基本的二叉树搜索,作为模板的一部分:针对ARM A7故障的优化GCC输出,gcc,assembly,optimization,arm,compiler-bug,Gcc,Assembly,Optimization,Arm,Compiler Bug,各位手臂装配专家注意 我有一些代码在优化时意外失败。我在一个简单的嵌入式设备单元测试中将其隔离。该代码是为ARM A7嵌入式环境构建的,使用gcc-ARM-8.3-2019.03-x86_64-ARM-eabi 该代码是一个基本的二叉树搜索,作为模板的一部分: map_node_s<KEY, VALUE> * _getMutableNode( const KEY & key, OUT map_node_s<KEY, VALUE> *** ptrT
map_node_s<KEY, VALUE> * _getMutableNode(
const KEY & key,
OUT map_node_s<KEY, VALUE> *** ptrToChildLink,
OUT map_node_s<KEY, VALUE> ** ptrToParent
)
{
map_node_s<KEY, VALUE> * parent = NULL;
map_node_s<KEY, VALUE> ** linkToChild = &_root;
map_node_s<KEY, VALUE> * current = *linkToChild;
while (current)
{
if (current->key == key)
{
break;
}
parent = current;
if (key < current->key)
{
linkToChild = &parent->left;
current = parent->left;
}
else
{
linkToChild = &parent->right;
current = parent->right;
}
}
*ptrToParent = parent;
*ptrToChildLink = linkToChild;
return current;
}
但是当运行时,结果是错误的排序,除非我关闭该方法的优化!!未优化的部件看起来完全不同
如果我添加一个断点,代码也可以工作。我不知道这会如何影响指令管道、I-cache或其他东西
此外,如果我做一个小的调整,代码将起作用:
if (key < current->key)
{
linkToChild = &parent->left;
}
else
{
linkToChild = &parent->right;
}
current = *linkToChild;
if(键key)
{
linkToChild=&parent->left;
}
其他的
{
linkToChild=&parent->right;
}
当前=*linkToChild;
发出
6317ff34: b168 cbz r0, 6317ff52 <_ZNSt3mapIiiE15_getMutableNodeERKiPPPSt10map_node_sIiiES6_+0x28>
if (current->key == key)
6317ff36: 680b ldr r3, [r1, #0]
6317ff38: 6806 ldr r6, [r0, #0]
6317ff3a: 429e cmp r6, r3
6317ff3c: d009 beq.n 6317ff52 <_ZNSt3mapIiiE15_getMutableNodeERKiPPPSt10map_node_sIiiES6_+0x28>
linkToChild = &parent->left;
6317ff3e: bfc7 ittee gt
6317ff40: 68c6 ldrgt r6, [r0, #12]
6317ff42: f100 040c addgt.w r4, r0, #12
linkToChild = &parent->right;
6317ff46: 6906 ldrle r6, [r0, #16]
6317ff48: f100 0410 addle.w r4, r0, #16
map_node_s<KEY, VALUE> * _getMutableNode(
6317ff4c: 4605 mov r5, r0
6317ff4e: 4630 mov r0, r6
6317ff50: e7f0 b.n 6317ff34 <_ZNSt3mapIiiE15_getMutableNodeERKiPPPSt10map_node_sIiiES6_+0xa>
6317ff34:b168 cbz r0,6317ff52
如果(当前->键==键)
6317ff36:680b ldr r3[r1,#0]
6317ff38:6806 ldr r6[r0,#0]
6317ff3a:429e cmp r6,r3
6317ff3c:d009北京时间6317ff52
linkToChild=&parent->left;
6317ff3e:bfc7 ITTE燃气轮机
6317ff40:68c6 ldrgt r6[r0,#12]
6317ff42:f100 040c地址w r4,r0,#12
linkToChild=&parent->right;
6317ff46:6906 ldrle r6[r0,#16]
6317ff48:F1000410地址w r4,r0,#16
映射\u节点\u s*\u getMutableNode(
6317ff4c:4605 mov r5,r0
6317ff4e:4630 mov r0,r6
6317ff50:e7f0 b.n 6317ff34
编译器生成的程序集是否有问题
是否可以插入一些其他asm指令来尝试检查执行问题?请准备一个。键的基本类型是什么??第一个程序集将其视为未签名类型,而第二个程序集将其视为已签名类型。在O2 asm中,我可以看到两次
current=parent->right;
,并且没有current=parent->left;
-您编译的源代码与所显示的源代码不同。您确定所显示的两个程序集片段之间的唯一区别是如何分配current
?我问这个问题是因为节点的内存布局似乎不同,我不明白为什么会受到影响这是一个RTOS错误(Zephyr)。我从调度程序中发现了注册表损坏。Geeze请准备一个。键的基本类型是什么??第一个程序集似乎将其视为未签名类型,而第二个程序集将其视为已签名类型。在O2 asm中,我可以看到current=parent->right;
两次,没有current=parent->left;
-您编译的源代码与所显示的源代码不同。您确定所显示的两个程序集片段之间的唯一区别是您如何分配当前
?我问这个问题是因为节点的内存布局似乎不同,我不明白为什么会受到该更改的影响。看起来这是一个RTObug(Zephyr)。我从调度程序中发现了寄存器损坏。Geeze
6317ff34: b168 cbz r0, 6317ff52 <_ZNSt3mapIiiE15_getMutableNodeERKiPPPSt10map_node_sIiiES6_+0x28>
if (current->key == key)
6317ff36: 680b ldr r3, [r1, #0]
6317ff38: 6806 ldr r6, [r0, #0]
6317ff3a: 429e cmp r6, r3
6317ff3c: d009 beq.n 6317ff52 <_ZNSt3mapIiiE15_getMutableNodeERKiPPPSt10map_node_sIiiES6_+0x28>
linkToChild = &parent->left;
6317ff3e: bfc7 ittee gt
6317ff40: 68c6 ldrgt r6, [r0, #12]
6317ff42: f100 040c addgt.w r4, r0, #12
linkToChild = &parent->right;
6317ff46: 6906 ldrle r6, [r0, #16]
6317ff48: f100 0410 addle.w r4, r0, #16
map_node_s<KEY, VALUE> * _getMutableNode(
6317ff4c: 4605 mov r5, r0
6317ff4e: 4630 mov r0, r6
6317ff50: e7f0 b.n 6317ff34 <_ZNSt3mapIiiE15_getMutableNodeERKiPPPSt10map_node_sIiiES6_+0xa>