山东省乡镇网站建设,公众号运营岗位职责,龙岩天宫山简介,广州做网站要多少钱4. 一些ODS定义
4.1. 特性#xff08;trait#xff09;
MLIR支持一个完全开放的生态系统#xff0c;因为任意方言都可以定义适合特定抽象层次的属性#xff08;attribute#xff09;、操作#xff08;operation#xff09;以及类型#xff08;type#xff09;。特性…4. 一些ODS定义
4.1. 特性trait
MLIR支持一个完全开放的生态系统因为任意方言都可以定义适合特定抽象层次的属性attribute、操作operation以及类型type。特性trait是抽象出实现细节以及在许多不同属性/操作/类型等之间通用的属性properties的机制。特性可用于说明这个对象特殊的属性以及约束包括一个操作是否有副作用或者它的输出是否与输入有相同的类型。操作特性的一些例子有Commutative、SingleResult、Terminator等。
4.1.1. 特性AttrSizedOperandSegments
特性AttrSizedOperandSegments是这样定义的
1777 def AttrSizedOperandSegments : NativeOpTraitAttrSizedOperandSegments;
Mlir codegen看到这个特性会为Op对象生成一个名为operand_segment_sizes的字典属性项。这个属性说明每个ODS声明的操作数变长或定长对应多少个实际操作数。它用于具有多个变长操作数但它们的大小关系静态未知。这个属性必须是与ODS声明操作数的元素个数相同的1维向量。这意味着即使某些操作数不是变长的这个属性仍然需要有一个元素对应其大小这将总是1。
4.1.2. 特性AttrSizedResultSegments
这个类与AttrSizedOperandSegments是类似的只不过适用于Op的结果对应于字典中result_segment_sizes一项。
4.2. Variadic
Variadic是这样定义的
308 class VariadicType type : TypeConstrainttype.predicate, type.description {
309 Type baseType type;
310 }
这个定义用在Op的arguments列表中比如AffineOps.td
69 let arguments (ins AffineMapAttr:$map, VariadicIndex:$mapOperands);
这里Index也是一个定义好的ODS类型
434 def Index : TypeCPred$_self.isa::mlir::IndexType(), index,
435 BuildableType$_builder.getIndexType();
一个Op允许使用任意多具有Variadic特性的操作数前提是这些操作数所包含的子操作数的个数是相同而且这些Variadic特性操作数可与非Variadic特性操作数混合使用。
区别AttrSizedXXX用作操作的属性描述的是操作所面对的操作数的形式。Variadic在这里通常用于描述为操作生成的方法的变长参数。
另外在这里及其他地方看到的变长数据类型比如VariadicRegion都只是占位符它们告诉mlir-tlbgen这个占位符对应的MLIR-IR是变长的要相应地生成解析代码。
4.3. 区域
4.3.1. 定义
区域region是MLIR块的有序列表。区域里的语义不是IR施加的。相反包含它的区域的操作定义了区域的语义。MLIR当前定义了两种类型的区域SSACFG区域它描述了基本块之间的控制流以及Graph区域它不要求基本块之间的控制流。操作里区域类型由RegionKindInterface描述。
区域没有名字或地址仅包含在区域里的基本块有。区域被包含在操作内并且没有类型或属性attributes。区域里的第一个基本块是称为“入口块”的特殊基本块。入口块的参数也是区域的参数。入口块不能作为其他基本块的后继者。
函数体是区域的一个例子它包含一个基本块的CFG并具有其他类型区域可能没有的额外的语义约束。例如在函数体中块终结符必须是去往另一个块的分支或者从一个函数返回其中return参数的类型必须匹配函数签名的结果类型。类似地函数参数必须匹配区域参数的类型与数量。一般来说具有区域的操作可以任意定义这些对应性correspondances。
4.3.2. 值作用域
区域提供了程序的分层封装hierarchical encapsulation引用即分支到不在同一个区域、作为引用源头的基本块即一个终结符操作是不可能的it is impossible to reference, i.e. branch to, a block which is not in the same region as the source of the reference, i.e. a terminator operation。类似地区域提供了值可见性的一个自然的辖域定义在一个区域里的值不会逃逸到包含它的区域如果有的话。默认地区域里的操作可以援引定义在外部区域的值只要包含它操作的操作数援引这些值是合法的但这局限于使用特性trait比如OpTrait::IsolatedFromAbove或定制的验证器。
例子 any_op(%a) ({ // if %a is in-scope in the containing region... // then %a is in-scope here too. %new_value another_op(%a) : (i64) - (i64) }) : (i64) - (i64) MLIR定义了一个泛化的“分层支配”的概念它跨层次工作定义一个值是否“在作用域内”可以被特定的操作使用。一个值是否可以被同一个区域里的另一个操作使用由区域类型定义。定义在一个区域里的值可以被在同一个区域里有一个父亲的操作使用当且仅当这个父亲可以使用这个值。由区域参数定义的值总是可以被深度包含在这个区域里的任何操作使用。在一个区域里定义的值不能在这个区域外使用。
4.3.3. 控制流与SSACFG区域
在MLIR里区域的控制流语义由RegionKind::SSACFG表示。非正式地这些区域支持这样的语义区域里的操作“顺序执行”。在执行一个操作前它的操作数有定义良好的值。在操作执行后操作数有相同的值且结果也有定义良好的值。在操作执行后执行基本块里的下一个操作直到基本块末尾的终结符操作在这个情形下将执行其他某个操作。确定下一条执行指令的是“控制流的传递”。
一般来说当控制流被传递到一个操作时MLIR不限制控制流何时进入或离开包含这个区域的操作。不过当控制流进入一个区域时它总是在这个区域的第一个块开始这个块称为入口块。结束每个基本块的终结符操作通过显明说明这个块的后继者基本块来表达控制流。控制流仅能传递给其中一个后继者基本块比如在一个branch操作或者在一个回到封装操作的return操作里。没有后继者的终结符操作仅能将控制传递回封装它的操作。在这些约束中终结符操作的特定语义是由所涉及的特定方言操作确定的。没有在终结符操作的后继者列表中的入口块以外的基本块被定义为不可到达可以被删除而不影响封装操作的语义。
虽然控制流总是通过入口块进入一个区域控制流可能通过任何一个具有合适终结符的基本块退出区域。Standard方言利用这个功能来定义具有单入口多出口Single-Entry-Multiple-ExitSEME的区域在区域中可能流经不同的基本块并从任一带有return操作的基本块退出。这个行为类似于大多数编程语言中函数体的行为。另外控制流还可能不能到达基本块或区域的末尾例如如果一个函数调用不返回。
例子 func accelerator_compute(i64, i1) - i64 { // An SSACFG region
^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %acond_br %cond, ^bb1, ^bb2^bb1:// This def for %value does not dominate ^bb2%value op.convert(%a) : (i64) - i64br ^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:...
}