MLIR笔记(4)

4.3.3. 控制流与SSACFG区域

在MLIR里,区域的控制流语义由RegionKind::SSACFG表示。非正式地,这些区域支持这样的语义:区域里的操作“顺序执行”。在执行一个操作前,它的操作数有定义良好的值。在操作执行后,操作数有相同的值且结果也有定义良好的值。在操作执行后,执行基本块里的下一个操作,直到基本块末尾的终结符操作,在这个情形下将执行其他某个操作。确定下一条执行指令的是“控制流的传递”。

一般来说,当控制流被传递到一个操作时,MLIR不限制控制流何时进入或离开包含这个区域的操作。不过,当控制流进入一个区域时,它总是在这个区域的第一个块开始,这个块称为入口块。结束每个基本块的终结符操作通过显明说明这个块的后继者基本块来表达控制流。控制流仅能传递给其中一个后继者基本块,比如在一个branch操作,或者在一个回到封装操作的return操作里。没有后继者的终结符操作仅能将控制传递回封装它的操作。在这些约束中,终结符操作的特定语义是由所涉及的特定方言操作确定的。没有在终结符操作的后继者列表中的(入口块以外的)基本块被定义为不可到达,可以被删除而不影响封装操作的语义。

虽然控制流总是通过入口块进入一个区域,控制流可能通过任何一个具有合适终结符的基本块退出区域。Standard方言利用这个功能来定义具有单入口多出口(Single-Entry-Multiple-Exit,SEME)的区域,在区域中可能流经不同的基本块,并从任一带有return操作的基本块退出。这个行为类似于大多数编程语言中函数体的行为。另外,控制流还可能不能到达基本块或区域的末尾,例如,如果一个函数调用不返回。

例子:

func @accelerator_compute(i64, i1) -> i64 { // An SSACFG region
^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a
  cond_br %cond, ^bb1, ^bb2

^bb1:
  // This def for %value does not dominate ^bb2
  %value = "op.convert"(%a) : (i64) -> i64
  br ^bb3(%a: i64)    // Branch passes %a as the argument

^bb2:
  accelerator.launch() { // An SSACFG region
    ^bb0:
      // Region of code nested under "accelerator.launch", it can reference %a but
      // not %value.
      %new_value = "accelerator.do_something"(%a) : (i64) -> ()
  }
  // %new_value cannot be referenced outside of the region

^bb3:
  ...
}
4.3.3.1. 带有多个区域的操作

包含多个区域的操作也完全确定了这些区域的语义。特别的,当控制流被传递到一个操作时,它可能把控制流转交给任一被包含的区域。当控制流退出一个区域并返回给提供包含的操作时,提供包含的操作可能将控制流传递给同一区域里的任一区域。操作也可能同时将控制流传递给被包含的多个区域。操作也可能将控制流传递入在其他操作里指定的区域,特别是那些像在一个call操作里使用的给定操作定义的值或符号。控制的这段通路通常与通过提供包含区域的基本块的控制流通路无关。

4.3.3.2. 闭包

区域允许定义创建一个闭包的操作,例如将区域的主体封装到它们生成的值里。它的语义仍然取决于操作。注意,如果操作触发了区域的异步执行,操作的调用者负责等待要执行的区域,确保任意直接使用的值保持存活。

4.3.4. 图区域

在MLIR中,区域里类似图的语义由RegionKind::Graph来表示。对没有控制流的并发语义,以及通用有向图数据结构的建模,图区域是合适的。图区域适用于表示耦合值之间的循环关系,这些关系没有基本的序。例如,一个图区域里的操作可能表示独立线程的控制流,具有表示数据流的值。就像通常在MLIR里一样,区域的特定语义完全由它包含的操作确定。图区域可能仅包含单个基本块(入口块)。

基本原理:当前的图区域被随意限制为单个基本块,虽然这个限制没有特别的语义方面的原因。加入这个限制使得稳定遍基本架构以及常用于处理图区域的遍恰当地处理反馈循环更容易。未来可能允许多基本块区域,如果出现要求它的用例。

在图区域中,MLIR操作自然地代表节点,而每个MLIR值代表连接源节点与多个目的节点的一条多边(multi-edge)。所有在区域里定义作为操作结果的值,作用域在区域内,可以被区域里的任意其他操作访问。在图区域中,一个基本块内存在的次序以及一个区域内基本块的次序是没有语义意义的,例如非终结符操作可以通过规范化任意重排。其他类型图,比如带有多个源节点与多个目的节点的图,也可以被图区域表示为MLIR操作。

注意,在图区域中的单个基本块里,或者基本块之间,会出现环。

"test.graph_region"() ({ // A Graph region
  %1 = "op1"(%1, %3) : (i32, i32) -> (i32)  // OK: %1, %3 allowed here
  %2 = "test.ssacfg_region"() ({
     %5 = "op2"(%1, %2, %3, %4) : (i32, i32, i32, i32) -> (i32) // OK: %1, %2, %3, %4 all defined in the containing region
  }) : () -> (i32)
  %3 = "op2"(%1, %4) : (i32, i32) -> (i32)  // OK: %4 allowed here
  %4 = "op3"(%1) : (i32) -> (i32)
}) : () -> ()
 

你可能感兴趣的:(MLIR笔记,mlir,笔记,编译)