From: Mehdi Amini Date: Mon, 6 May 2019 04:43:02 +0000 (-0700) Subject: Specify Regions in LangRef X-Git-Tag: llvmorg-11-init~1466^2~1821 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e2e89f5c834954e646eba69f56d58617d2ca5b02;p=platform%2Fupstream%2Fllvm.git Specify Regions in LangRef Region is the generalization of a function body (a list of blocks forming a CFG) to be allowed to be enclosed inside any operation. This nesting of IR is already leveraged in the affine dialect to support `affine.for`, `affine.if`, and `gpu.launch` operations. -- PiperOrigin-RevId: 246766830 --- diff --git a/mlir/g3doc/LangRef.md b/mlir/g3doc/LangRef.md index 30d278e..e261a84 100644 --- a/mlir/g3doc/LangRef.md +++ b/mlir/g3doc/LangRef.md @@ -1223,14 +1223,15 @@ argument-list ::= type attribute-dict? (`,` type attribute-dict?)* | /*empty*/ named-argument ::= ssa-id `:` type attribute-dict? function-attributes ::= `attributes` attribute-dict -function-body ::= `{` block+ `}` +function-body ::= region ``` An external function declaration (used when referring to a function declared in -some other module) has no body. A function definition contains a control -flow graph made up of one or more blocks. While the MLIR textual form provides a -nice inline syntax for function arguments, they are internally represented as -"block arguments" to the first block in the function. +some other module) has no body. A function definition contains a +[region](#regions) made up of one or more blocks forming the function body. +While the MLIR textual form provides a nice inline syntax for function +arguments, they are internally represented as "block arguments" to the first +block in the region. Examples: @@ -1246,6 +1247,107 @@ func @count(%x: i64) -> (i64, i64) } ``` +## Regions + +A region is a CFG of MLIR [Blocks](#blocks). Regions serve as a generalization +of a function body that can be nested under arbitrary operations. A region +semantics is defined by the containing entity (operation or function). Regions +do not have a name or an address, only the blocks contained in a region do. + +The first block in the region cannot be a successor of any other block. The +arguments of this block are treated as arguments of the region. The syntax for +the region is as follows: + +``` {.ebnf} +region ::= region-signature? region-body +region-signature ::= `(` argument-list `)` (`->` function-result-type)? +region-body ::= `{` block+ `}` +``` + +The function body is an example of a region, the body of an `affine.for` +operation is another example, this time of an single-block region. + +Regions provide nested control isolation: it is impossible to branch to a block +within a region from outside it, or to branch from within a region to a block +outside it. Similarly it provides a natural scoping for value visibility: SSA +values defined in a region don't escape to the enclosing region if any. By +default, a region can referenced values defined outside of the region, whenever +it would have been legal to use them as operands to the enclosing operation. +This can be further restricted using custom verifier. + +Example: + +```mlir {.mlir} +func $@accelerator_compute(i64, i1) -> i64 { +^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a + br_cond %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"() { + ^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 +... +} +``` + +Regions are Single-Entry-Multiple-Exit (SEME). It means that control can only +flow into the first block of the region, but can flow out of the region at the +end of any of the blocks it contains. (This behavior is similar to that of +functions in most programming languages). Nonetheless, when exiting the region +from any of its multiple exit points, the control flows to the same successor. + +Regions present in an operation can be executed any number of times. The IR does +not guarantee if a region passed as an argument to an operation will be +executed; if so, how many times and when. In particular, a region can be +executed zero, one or multiple times, in no particular order with respect to +other regions or operations. It may be executed as a part of an operation, or by +some later operation using any values produced by the operation that contains +the region. The successor to a region’s exit points may not necessarily exist: +regions enclosing non-terminating code such as infinite loops are possible, as +well as an operation implementing an infinite loop over a region. Concurrent or +asynchronous execution of regions is unspecified. Operations may define pecific +rules of execution, e.g. sequential loops or switch-like blocks. + +In case of zero executions, control does not flow into the region. In case of +multiple executions, the control may exit the region from any of the region exit +points and enter it again at its entry point. It may also enter another region. +If an operation has multiple region arguments, the semantics of the operation +defines into which regions the control flows and in which order, if any. An +operation may trigger execution of regions that were specified in other +operations, in particular those that defined the values the given operation +uses. When all argument regions were executed the number of times required by +the operation semantics, the control flows from any of the region exit points to +the original control-successor of the operation that triggered the execution. +Thus operations with region arguments can be treated opaquely in the enclosing +control flow graph, providing a level of control flow isolation similar to that +of the call operation. + +Regions allow to define an operation that creates a closure, for example by +“boxing” the body of the region into a value they produce. It remains up to the +operation to define its semantics. In this situation, the value “containing” the +region may be passed to or returned from a function/region, at which point the +values defined in dominating blocks are no longer accessible. If this region +directly uses such values, passing a value “containing” it across function +boundaries or using it in operations leads to undefined behavior. This is +similar to returning a lambda capturing a reference to a local variable in C++. +Note that if an operation triggers asynchronous execution of the region, it is +under the responsibility of the operation caller to wait for the region to be +executed guaranteeing that any directly used values remain live. + +Regions produce a (possibly empty) list of values. For function body regions, +`return` is the standard region-exiting terminator, but dialects can provide +their own. For regions passed as operation arguments, the operation semantics +defines the relation between the region results and the operation results. + ## Blocks Syntax: