如何在llvm中构建新的SDNode?

时间:2015-09-26 21:02:56

标签: llvm llvm-ir

我正在尝试在llvm backend(llc)中添加对新arch的支持。但是我发现添加一个有2个结果的新SDNode很困难。我在sparc arch中看到UMUL / SMUL有2个结果(第二个是Y)所以他们定义了:

let Defs = [Y] in {
  defm UMUL : ...
  defm SMUL : ...
}

let Uses = [Y], ... in
  def RDY : ...

并在select函数中看起来像:

 SDNode *Mul = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Glue,
                                     MulLHS, MulRHS);
// The high part is in the Y register.
return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDValue(Mul, 1));

所以他们正在使用结果1 - 我认为是Y ...

在我的情况下,我有一个影响cc位的指令。 所以我试着用同样的方法。我在Xinstr中定义了:

def SUBCri : ...>{
  let Defs = [CRZ];
}

let Uses = [CRZ] in {
  def BRC_Z : ... (outs), (ins target:$dst),
}

并在select函数中:

    SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::Glue);
    SDNode * CondCode = CurDAG->getMachineNode(X::SUBCri, dl, VTs, ops);
    SDNode * ResNode = CurDAG->SelectNodeTo(Node, X::BRC_Z, MVT::Other, Dst,
            SDValue(CondCode, 1));

但我得到了下一个错误:

Assertion `NumMIOperands >= II.getNumOperands() && NumMIOperands <= II.getNumOperands() + II.getNumImplicitDefs() + NumImpUses && "#operands for dag node doesn't match .td file!"' failed.

所以我的问题是:

  1. 定义SDNode的正确方法是什么?
  2. SDVTList VT是什么意思?是结果吗? (SDVTList VTs)的顺序是什么意思?
  3. 什么是OpsArray?是投入吗?插入输入的正确顺序是什么?我在&#34; countOperands&#34;他们检查功能,看看最后一个是胶水。什么意思胶水是最后的?在同一个函数中,他们检查MVT :: Other是否也存在?这意味着什么?
  4. 最后 - 我做错了什么?为什么我得不到第二个结果?为什么我一直都会收到这个错误?

1 个答案:

答案 0 :(得分:2)

This should really be a comment, but I have no rep. Some hints that may hopefully help:

  • VT stands for ValueType. LLVM needs to know the type(s) of the return values of each SDNode. By passing VTs into getMachineNode, you create a new SDNode that returns as many values as there are in the SDVTList, with the specified types.

  • "Glue" is a special ValueType that doesn't actually hold a value. It's just used to ensure that two glued SDNodes don't get separated when instruction scheduling happens.

  • "ops" are indeed the incoming inputs.

  • The order of inputs and return values should be exactly the order specified in TableGen.

  • I'm not sure about this, but I don't think Defs are turned into implicit return values. You might have to manually create a CopyFromReg node, to grab the register that is written to.

  • MVT::Other represents a "chain", a way to ensure that instructions with side effects are not reordered relative to each other.

Do read the doxygen docs, they're fairly good at explaining the individual functions (even if a bit lacking in the bigger-picture).

Try starting here: http://llvm.org/docs/doxygen/html/classllvm_1_1SelectionDAG.html