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