c#数组赋初值_方舟编译器学习笔记24 以一维数组为例看MAPLE IR中存储访问

MAPLE IR中专门有一系列的存储访问指令,主要有:dassign,dread,iassign,iread,iassignoff,iassignfpoff,ireadoff,ireadfpoff,regassign和regread。在这些指令中,dassign、dread、iassign和iread比较常用;dassign和dread是直接赋值和直接引用;iassign和iread是间接赋值和间接引用,字符串“dassign”、“dread”、“iassign”和“iread”则是这些指令的操作码,后跟的操作数通常在()之内。

直接赋值和直接引用属于直接访问,直接访问通常可以映射到pseudo-registers,pseudo-registers只能存储基本类型。官方文档中提到:

Pseudo-registers are referred to by the '%' prefix followed by a number. 
This distinguishes them from other local variables that are not pseudo-registers, 
as their names cannot start with a number.

但是实际生成的MAPLE IR之中,寄存器如图所示:

bd5c643b9389cb0512db171383d1d572.png

从这里寄存器里明显可以看到基本类型i32,也可以看到复杂类型<*<[] i32>>和<*<$Ljava_2Fio_2FPrintStream_3B>>,但是其命名规则都是一致的,并未出现文档中所说的区别。

笔者根据MAPLE IR文档中的源码,建立了一个简单的关于数组访问的测试用例,源码如下:

8c3c11e868d3798949d76685a3b6213e.png

将其编译成为.mpl文件,阅读其中间代码,分析数组的存储访问,总结起来有这么几点:

1、数组的空间分配

0364193b25aa4de3081ac14a75a0c43c.png

这里用了两次dassign,第一次是将数组的元素个数3给了%Reg0_I,第二次是根据%Reg0_I申请了一块内存,分配给%Reg0_R735。

2、数组元素的初始化:

49ba4e1248de9c5edd93116721ed6c9d.png

使用了两次dassign,将常数0和1分别放到了%Reg1_I和%Reg2_I之中,前者是数组下标,后者是初值。然后再iassign之中,用了两次dread将这两个值再从寄存器之中读取出来,然后通过iassign进行复制操作。这段代码只是将数组下标为0的元素赋值为1,后续类似的操作连续还进行了两次,才完成了对数组的初始化。iassign和文档中的形式也不太一样,文档中的形式为:

iassign<*i32>(
  array a32 <* [10] i32> (addrof a32 $a, dread i32 $i), # <* [10] i32> indicates pointer to an array of 10 ints
  dread i32 $i)

3、数组元素的赋值

在数组完成初值的赋值之后,根据源码要对下标为2的元素赋值为2。对应的MAPLE IR代码为:

bfefff79e6d37c210077f7a722b4d1b4.png

将常数2进行dassign给了%Reg0_I,然后将%Reg0_I 进行dassign 给了%Reg5_I,其实它们两个都是存储了一个常数2。然后用两个dread取出2,接着用iassign给数组%Reg4_R735的下标为2的元素赋值2。

4、数组的赋值

本文的第一个图:

bd5c643b9389cb0512db171383d1d572.png

其中定义了两个数组的寄存器:%Reg0_R735和%Reg4_R735。我们通过1、2、3的分析也可以看到,初始化分配空间和赋初值的时候,用的都是%Reg0_R735,而3中再对下标为2的元素赋值2的时候,操作采用的是%Reg4_R735。其实,二者的内容是相同的,在代码中有如下语句:

7b6ff4ddd440328f7dc911a4f81fec32.png

%Reg4_R735是直接从%Reg0_R735进行dassign操作过来的。

——————

总结:

1、从MAPLE IR来看,方舟的MAPLE IR应该不是SSA,因为其中的寄存器变量存在多次赋值使用的情况。

2、因为获取数据是dassign这种形式,所以4之中这种情况也就是必然了。

3、语句中经常在中间位置有一个0,这是field-ID,涉及结构体内部的field-ID的编号,本例中不涉及这些内容,所以生成的field-ID都是0

需要关注的问题:

1、源码和文档中pseudo-registers的命名规则的不一致。

2、源码和文档中iassign的使用差异问题。

——————

注:文中的测试用例回头会上传到:方舟编译器:isrc-cas/openarkcompiler。这是软件所智能软件研究中心在维护的一个方舟编译器版本,其代码并不是总和官方一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值