Compiler construction 计算一组指令的依赖关系图

Compiler construction 计算一组指令的依赖关系图,compiler-construction,Compiler Construction,在一系列可能的说明中: 1: A[i] = B[i] 2: B[i] = A[i] + D[i - 1] 3: C[i] = A[i] - D[i - 1] 4: D[i] = B[i] + C[i] 我想计算依赖关系图,其结果如下: 这样做的有效算法是什么 我当前的实现如下所示: 运行所有指令并生成上次看到的数组 甲:,, B:[2], C:[3], D:[4] 对于每个指令,iff都是赋值: 分为左和右两部分 生成新的节点(左) 对于right中的每个标识符:创建新的边(左,最后

在一系列可能的说明中:

1: A[i] = B[i]
2: B[i] = A[i] + D[i - 1]
3: C[i] = A[i] - D[i - 1]
4: D[i] = B[i] + C[i]
我想计算依赖关系图,其结果如下:

这样做的有效算法是什么

我当前的实现如下所示:

  • 运行所有指令并生成上次看到的
    数组

    甲:,, B:[2], C:[3], D:[4]

  • 对于每个指令,iff都是赋值:

    • 分为左和右两部分

    • 生成新的
      节点(左)

    • 对于
      right
      中的每个标识符:创建新的
      边(左,最后一次看到[右])


在Steven Muchnick的《高级编译器设计与实现》一书中,算法9.6介绍了一种为基本块调度构造依赖DAG的方法。它还考虑不同操作之间的延迟(以便以后可以根据某种启发式选择指令)

算法首先需要检查冲突(即,DAG中已经存在的指令) 如果没有冲突,我们将节点j添加到DAG的根。否则,如果存在冲突,则为每个冲突k在k和j之间添加一条边。一些延迟函数给出了标签

该方法的时间复杂度为O(N²)

    #= Pseudocode of the build dag procedure (Some simplified ICAN notation)=# 
Build_dag(numberOfInstructions, Instructions)
    begin 
         DAG = {Nodes =  {}, Edges = {}, Label = {}, Roots{}}
         Conflicts = A set of integers representing conflicts
         j, k #= Integers for indexing=#
         for j in 1 to numberOfInstructions
              D.Nodes ∪= {j}
              Conflicts = {}
              for k = 1 to j - 1
                  if Conflict between Instructions[k] and Instructions[j]
                      Conflicts ∪= {k}
                  end
              end
              if isEmpty(Conflicts)
                  DAG.Roots ∪= {j}
              else 
                 for each k in Conflicts
                     DAG.Edges ∪= {k->j} #=Adds an edge between node k and node j=#
                     DAG.Label(k, j) = Latency(Instructions[k], 1, Instructions[j], IssueLatency + 1)
                 end
              end
          end
      return DAG
end