[LLVMdev] Isel DAG documentation?

Tim Northover t.p.northover at gmail.com
Sun Mar 9 00:02:32 PST 2014


Hi David,

>   [(set GR32:$rD, globaladdr:$addr)]

> It seems to have somehow managed to create a cycle in the DAG, which is
> of course wrong. But how?

When I write a similar pattern into the ARM .td files and look at
(from the build directory) lib/Target/ARM/ARMGenDAGISel.inc, I see:

/*56478*/   /*SwitchOpcode*/ 13, TARGET_VAL(ISD::GlobalAddress),// ->56494
/*56481*/     OPC_RecordNode, // #0 = $src
/*56482*/     OPC_CheckType, MVT::i32,
/*56484*/     OPC_CheckPatternPredicate, 4, // (!Subtarget->isThumb())
/*56486*/     OPC_MorphNodeTo, TARGET_VAL(ARM::MOVi32imm), 0,
                  1/*#VTs*/, MVT::i32, 1/*#Ops*/, 0,
              // Src: (globaladdr:i32):$src - Complexity = 3
              // Dst: (MOVi32imm:i32 (globaladdr:i32):$src)

The first lines are fairly unimportant, but the last two show what the
DAG thinks it's doing and make it clear why the recursion happens.
It's because the globaladdr node doesn't actually get changed during
matching, so LLVM is just going to encounter it again at the next step
and perform the same substitution.

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)>;

> (2) Even when I do manage to generate machine instructions, they're all
> discarded because they're dead. This is leading to very fast but
> slightly flawed code (all I get is a return instruction).
>
> My best guess is that this is because I'm incorrectly wiring up the
> function outputs, resulting in the compiler discarding the instructions
> because the result isn't used.

That sounds most likely. If you run "llc -print-after-all" you should
be able to see the MachineInstr dataflow before it all gets removed.
For example a simple "ret i32* @glob" function (on ARM again) gives
me:

BB#0: derived from LLVM BB %0
        %vreg0<def> = MOVi32imm <ga:@addr>; GPR:%vreg0
        %R0<def> = COPY %vreg0; GPR:%vreg0
        BX_RET pred:14, pred:%noreg, %R0<imp-use>

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.

Which other target's LowerReturn are you using? That's probably the
first thing we should check is doing its job. The pictures from of
"llc -view-isel-dags" and "llc -view-sched-dags" on a simple function
returning something would be very useful there. If you can upload them
somewhere (or attach them) I'll take a look and see if anything looks
wrong.

Cheers.

Tim.



More information about the llvm-dev mailing list