[LLVMdev] Isel DAG documentation?

David Given dg at cowlark.com
Sun Mar 9 15:40:41 PDT 2014


On 3/9/14, 8:02 AM, Tim Northover wrote:
[...]
> I'd want that Dst globaladdr to be a tglobaladdr (target globaladdr)
> since LLVM knows it shouldn't try to select target nodes. Existing
> targets mostly do that during ISelLowering for various reasons, but
> for your case a separate pattern can probably do the job:
> 
> def : Pat<(globaladdr:$addr), (MOVar tglobaladdr:$addr)>;

So if I've understood what this does correctly: instead of just
describing a machine instruction to LLVM and letting it figure out how
to transform the DAG tree into machine instructions, we're giving it an
explicit rule about how to transform globaladdr nodes? That seems
sensible... but I'm afraid it doesn't work, dying in precisely the same
way as above.

My rules look like this:

def MOVar : S32<
  (outs GR32:$rD), (ins i32imm:$addr), // i32imm is wrong here
  "mov $rD, $addr",
  [(set GR32:$rD, tglobaladdr:$addr)]
>;
def : Pat<(globaladdr:$addr), (MOVar tglobaladdr:$addr)>;

In the crash dump, the DAG is dumped. The beginning looks like this:

Offending node:
0x7fd14880c010: i32 = <<Unknown Machine Node #65508>> 0x7fd14880c010
[ORD=2] [ID=1]
  0x7fd14880c010: i32 = <<Unknown Machine Node #65508>> 0x7fd14880c010
[ORD=2] [ID=1]
  ...etc...

(I'm pretty sure that machine node #65508 is the MOVar, but how do I
find out for sure?)

My gut feeling is that we have a node n, and the pattern fragment above
is transforming this to (MOVar n) *at the same address*, so n points at
the new transformed node. Thus, forming a cycle. The other targets don't
suffer from this because they represent address as complex patterns and
use custom-written selectors to pull the information out of the
globaladdr node and represent it in a different way. I'd really rather
not do this, as I'd rather like to try and suss out pattern based
codegen before trying to customise it; is it actually possible to do
this using pure patterns?

[...]
> The important point here is that the BX_RET has some kind of <imp-use>
> of the registers that will be used to return (%R0 in this case). It
> gets added first in XYZTargetLowering::LowerReturn, and then selected
> in the .td file using a variadic node.

Yep --- it wasn't marked as variadic, and so my RET instruction had no
inputs. Fixing this makes it generate code quite happily. Ta.

-- 
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│
│ "You cannot truly appreciate _Atlas Shrugged_ until you have read it
│ in the original Klingon." --- Sea Wasp on r.a.sf.w

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 876 bytes
Desc: OpenPGP digital signature
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140309/89c47e47/attachment.sig>


More information about the llvm-dev mailing list