Next: Lambda, Previous: Number of iterations, Up: Loop Analysis and Representation
用于数据相关性分析的代码可以在tree-data-ref.c中找到,接口和数据结构在tree-data-ref.h中描述。用来计算对于给定循环的所有数组和指针引用的数据相关性的函数为compute_data_dependences_for_loop
。该函数目前被用于线性循环转换和向量化过程。在调用该函数之前,必须分配两个向量:第一个向量将会包含在被分析的循环体中的数据引用集,第二个将会包含数据引用之间的依赖关系。因此,如果数据引用向量的大小为n
,则包含依赖关系的向量将包含n*n
个元素。但是,如果被分析的循环包含副作用,例如对数据引用有潜在干扰的调用,则分析会在扫描循环体中的数据引用时停住,并在依赖关系数组中插入一个chrec_dont_know
。
数据相关性是在扫描循环体时,按照特定顺序发现的:循环体按照执行顺序分析,每条语句的数据引用被压入数据引用数组的尾部。两个数据相关性在程序中的语法位置,和在数据相关性数组具有相同的顺序。这种语法顺序在一些经典数据相关性测试中很重要,并且将这中顺序映射到数组的元素可以避免对循环体表示的昂贵查询开销。
目前处理了三种类型的数据相关性:ARRAY_REF, INDIRECT_REF和COMPONENT_REF。数据相关性的数据结构体为data_reference
,其中data_reference_p
为指向数据相关性结构体的指针名。结构体包含了以下元素:
base_object_info
:
提供了关于数据引用的基本对象的信息,以及访问函数代表了数据引用在循环中相对于它的基的演变。这些访问函数。例如,对于一个引用a.b[i][j]
,基本对象为a.b
,其中一个针对每个数组下标的访问函数为:{i_init, + i_step}_1, {j_init, +, j_step}_2
。
first_location_in_loop
: 提供了循环中由数据引用访问的第一个位置,以及用来表示相对于该位置的演化的访问函数。该数据用来支持指针,而不是数组(具有基对象的)。指针访问被表示为从循环中的第一个位置开始的一维访问。例如:
for1 i for2 j *((int *)p + i + j) = a[i][j];
对于p + i
,指针访问的访问函数是{0, + 4B}_for2
。对于a
,数组的访问函数是{i_init, + i_step}_for1
和{j_init, +, j_step}_for2
。
通常,指针指向的对象或者是不可知的,或者是我们不能证明访问被限制在这些对象的边界中。
两个数据引用只有在最起码有一个表示的所有域都适合于这两个数据引用时,才能够进行比较。
目前测试数据相关性的策略为:如果a
和b
都由数组来表示,则比较a.base_object
和b.base_object
;如果它们相等,则应用相关性测试(使用基于base_objects的访问函数)。如果a
和b
都由指针表示,则比较a.first_location
和b.first_location
;如果它们相等,则应用相关性测试(使用基于第一位置的访问函数)。但是,如果a
和b
的表示不同,只能尝试去证明它们的基肯定不相同。
描述两个数据引用之间关系的结构体是data_dependence_relation
,指向这种结构体的指针的简短名字为ddr_p
。该结构体包含:
are_dependent
,如果分析证明了两个数据引用之间没有相关性,则设置为chrec_known
;如果分析不能判定任何有用的结果,并且这些数据引用可能存在相关性,则设为chrec_dont_know
;如果数据引用间存在相关性,则设置为NULL_TREE
,并且该相关性的描述在dir_vects
和dist_vects
数组的下标中给出。
subscripts
,包含了数据引用的每个下标的描述。给出两个数组访问,下标为对于给定维数的访问组合。例如,给定A[f1][f2][f3]
和B[g1][g2][g3]
,则有三个下标:(f1, g1), (f2, g2), (f3, g3)
。
dir_vects
和dist_vects
,包含了使用方向和距离依赖向量的数据相关典型表示。loop_nest
,包含了距离和方向向量指向的循环。
有一些函数可以很好的打印由数据相关分析抽出的信息:dump_ddrs
打印最详尽的数据依赖关系数组,dump_dist_dir_vectors
只打印数据依赖关系数组的典型的距离和方向向量,dump_data_references
打印数据引用数组中的详细的数据引用。