LLVM学习笔记(17)补

栏目: 服务器 · 编程工具 · 发布时间: 5年前

内容简介:3.4.2.4.3.2.回到TreePattern::InferAllTypes,既然现在类型有可能已经具体化了,那么通过下面的方法尝试简化这棵TreePattern树。

3.4.2.4.3.2. 简化

回到TreePattern::InferAllTypes,既然现在类型有可能已经具体化了,那么通过下面的方法尝试简化这棵TreePattern树。

2216  static bool SimplifyTree (TreePatternNode *&N) {

2217  if (N->isLeaf())

2218  return false;

2219 

2220  // If we have a bitconvert with a resolved type and if the source and

2221    // destination types are the same, then the bitconvert is useless, remove it.

2222  if (N->getOperator()->getName() == "bitconvert" &&

2223  N->getExtType(0).isConcrete() &&

2224  N->getExtType(0) == N->getChild(0)->getExtType(0) &&

2225  N->getName().empty()) {

2226  N = N->getChild(0);

2227  SimplifyTree(N);

2228  return true;

2229  }

2230 

2231  // Walk all children.

2232  bool MadeChange = false;

2233  for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {

2234  TreePatternNode *Child = N->getChild(i);

2235  MadeChange |= SimplifyTree(Child);

2236  N->setChild(i, Child);

2237  }

2238  return MadeChange;

2239  }

可以看到,目前只有bitconvert子树才可能简化。Bitconvert代表了整数、浮点及向量值之间的转换,源与目标值都有相同的大小。如果源与目标值类型相同,这个转换可以丢弃。

3.4.2.4.3.3. ​​​​​​​ 类型的最后确定

在TreePattern::InferAllTypes()函数的入口,当前树的具名节点(即node:$ name 的名字 name )被保存在NamedNodes容器。現在2260行遍历这些名字。首先,如果InferAllTypes()传入了非空的参数InNamedTypes,需要确保名字出现在InNamedTypes里。并使用InNamedTypes中对应节点的类型信息来更新当前节点的类型。这个用法出现在Instruction与Pattern定义的处理中,后面会看到。

在此之后,如果NamedNodes容器里存在多个节点对应同一个名字的情形,它们的类型必须一致(2300~2310行)。

而在上述过程里,一旦有节点的类型发生变化,就要回到2252行重新进行处理,直达没有节点的类型在一次处理过程中改变为止。这时,这棵(些)TreePattern树所有节点的类型都应该确定了,这由下面的方法来判定。

498     bool ContainsUnresolvedType () const {

499     for (unsigned i = 0, e = Types.size(); i != e; ++i)

500     if (!Types[i].isConcrete()) return true;

501    

502     for (unsigned i = 0, e = getNumChildren(); i != e; ++i)

503     if (getChild(i)->ContainsUnresolvedType()) return true;

504     return false;

505     }

从TreePattern::InferAllTypes()回到CodeGenDAGPatterns::ParsePatternFragments(),对PatFrag定义的处理就此完成。

v7.0 ContainsUnresolvedType() 的定义是:

1561  bool TreePatternNode::ContainsUnresolvedType(TreePattern &TP) const {

1562  for (unsigned i = 0, e = Types.size(); i != e; ++i)

1563  if (!TP.getInfer().isConcrete(Types[i], true))

1564  return true;

1565  for (unsigned i = 0, e = getNumChildren(); i != e; ++i)

1566  if (getChild(i)->ContainsUnresolvedType(TP))

1567  return true;

1568  return false;

1569  }

1563 TypeInfo isConcrete() 方法通过 TypeSetByHwMode sValueTypeByHwMode() 来执行:

253     bool isConcrete( const TypeSetByHwMode &VTS, bool AllowEmpty) const {

254     return VTS.isValueTypeByHwMode(AllowEmpty);

255     }

下面 73 行遍历 TypeSetByHwMode 实例中的 Map 容器( std::map ), 74 行检查其中的 MachineValueTypeSet 容器是否有设置了比特位(对应一个 MVT )。

72       bool TypeSetByHwMode::isValueTypeByHwMode (bool AllowEmpty) const {

73       for ( const auto &I : * this ) {

74       if (I.second.size() > 1)

75       return false;

76       if (!AllowEmpty && I.second.empty())

77       return false;

78       }

79       return true;

80       }

AllowEmpty false 的情形下, Map 容器里每个 MachineValueTypeSet 容器中只设置了一个比特位, TypeSetByHwMode sValueTypeByHwMode() 才返回 true

3.4.2.4.4. ​​​​​​​OperandWithDefaultOps

接下来,CodeGenDAGPatterns构造函数处理OperandWithDefaultOps派生定义。这个定义在文件Target.td里。

664     class OperandWithDefaultOps dag defaultops>

665     : Operand {

666     dag DefaultOps = defaultops;

667     }

TableGen使用这个定义用于代表缺省值。它典型的用法有(摘自AMDGPUInstructions.td):

def InstFlag : OperandWithDefaultOps ops (i32 0))>;

在这个定义里,缺省值是0。InstFlag可以用在dag中作为操作数,表示自己所代表的缺省值。

CodeGenDAGPatterns对OperandWithDefaultOps定义的处理相当简单。

2507  void CodeGenDAGPatterns::ParseDefaultOperands () {

2508  std::vector DefaultOps;

2509  DefaultOps = Records.getAllDerivedDefinitions("OperandWithDefaultOps");

2510 

2511  // Find some SDNode.

2512  assert (!SDNodes.empty() && "No SDNodes parsed?");

2513  Init *SomeSDNode = DefInit::get(SDNodes.begin()->first);

2514 

2515  for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) {

2516  DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");

2517 

2518  // Clone the DefaultInfo dag node, changing the operator from 'ops' to

2519      // SomeSDnode so that we can parse this.

2520  std::vector > Ops;

2521  for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)

2522  Ops.push_back(std::make_pair(DefaultInfo->getArg(op),

2523  DefaultInfo->getArgName(op)));

2524  DagInit *DI = DagInit::get(SomeSDNode, "", Ops);

2525 

2526  // Create a TreePattern to parse this.

2527  TreePattern P(DefaultOps[i], DI, false, * this );

2528  assert (P.getNumTrees() == 1 && "This ctor can only produce one tree!");

2529 

2530  // Copy the operands over into a DAGDefaultOperand.

2531  DAGDefaultOperand DefaultOpInfo;

2532 

2533  TreePatternNode *T = P.getTree(0);

2534  for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {

2535  TreePatternNode *TPN = T->getChild(op);

2536  while (TPN->(P, false))

2537  /* Resolve all types */ ;

2538 

2539  if (TPN-> ContainsUnresolvedType ()) {

2540  PrintFatalError("Value #" + Twine(i) + " of OperandWithDefaultOps '" +

2541  DefaultOps[i]->getName() +

2542  "' doesn't have a concrete type!");

2543  }

2544  DefaultOpInfo.DefaultOps.push_back(TPN);

2545  }

2546 

2547  // Insert it into the DefaultOperands map so we can find it later.

2548  DefaultOperands[DefaultOps[i]] = DefaultOpInfo;

2549  }

2550  }

SDNodes是CodeGenDAGPatterns的std::map类型容器,LessRecordByID以Record的ID来排序。因此2513行获取第一个出现的SDNode定义,这是imm。因此,2521~2524行将指定的缺省值(DefaultOps)封装为一个DagInit:(imm DefaultOps),由TreePattern构造函数构造该DagInit的模式树。由容器DefaultOperands(std::map)保存这些生成的模式树。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First PHP & MySQL

Head First PHP & MySQL

Lynn Beighley、Michael Morrison / O'Reilly Media / 2008-12-29 / USD 44.99

If you're ready to create web pages more complex than those you can build with HTML and CSS, Head First PHP & MySQL is the ultimate learning guide to building dynamic, database-driven websites using P......一起来看看 《Head First PHP & MySQL》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具