[llvm-dev] Expanding a PseudoOp and accessing the DAG

Krzysztof Parzyszek via llvm-dev llvm-dev at lists.llvm.org
Thu Jan 14 06:05:04 PST 2016


On 1/13/2016 4:47 PM, Phil Tomson wrote:
>
> First off, I got this idea from the LLVM Cookbook chapter 8: Writing an
> LLVM Backend: Lowering to multiple instructions. (now I'm having my
> doubts as to whether this is the right approach)

There is a pass "ExpandISelPseudos", which handles instructions with 
custom inserters.  You can mark instructions as having custom inserters 
in the .td files and then override the EmitInstrWithCustomInserter 
function to deal with them.


> Let me explain at the assembly level what I'm trying to accomplish.
>
> We're trying to make position independent executables, so we intend to
> have a switch like -fPIE. In that case we've designated some registers
> to be pointers to various address spaces (and our processor is rather
> complicated so there are several address spaces).
>
> Right now,  given a global variable called 'answer' in C we end up with
> the following in the .s file:
>
>    movimm    r1, %rel(answer) # r1 <- offset to 'answer' symbol
>    load    r1, r1, 0                     # r1<-mem[r1+0]
>
> This isn't correct because it should be relative to the GRP register if
> the PIE mode is chosen, what I'd like to get is either:
>
>    movimm   r1, %rel(answer)
>    addI         r1, GRP              # r1 <- r1 + GRP
>    load         r1, r1, 0               # r1 <- mem[r1+0]
>
> Or even better:
>
>    movimm   r1, %rel(answer)
>    load         r1, r1, GRP      # r1 <- mem[r1+GRP]
>
> What I'm getting at the moment is just this part:
>
>    load        r1, r1, GRP
>
> So the movimm is missing. That's because I've added the Pseudo
> instruction RelAddr and GlobalAddress nodes get converted to RelAddr
> nodes in LowerGlobalAddress.... They used to get converted to the MVINI
> node type there prior to adding the RelAddr pseudo inst.
>
> It feels like more of this needs to be done in the LowerGlobalAddress
> function, but I have no idea how to do it there - you seem to only be
> able to get one instruction out of a lowering like that, not multiple
> instructions. It also seems like (as you point out) the expansion phase
> is too late to be doing it.

Here's what I would do (based on what I understand about your target so 
far):

Define two additional ISD opcodes, specific to your target. One to 
denote a "normal" address, the other to mean "address using GRP".  For 
example (you can invent better names for them): XSTGISD::ADDR_NORMAL and 
XSGTISD::ADDR_USE_GRP. Each of them will take a global address as an 
operand and return an address, and their only function will be to serve 
as a "tag" for the instruction selection algorithm to be able to apply 
different selection patterns to them.

In the .td file, define SDNodes corresponding to these opcodes, e.g. 
"addr_normal" and "addr_use_grp".  Then, you can have these patterns for 
loads:

// Match a load from a non-relocatable address to a simple load
// instruction (with offset 0):
def: Pat<(load (addr_normal tglobaladdr:$addr)),
          (load tglobaladdr:$addr, 0)>;
// Match load from a relocatable address to a load with GRP:
def: Pat<(load (addr_use_grp tglobaladdr:$addr)),
          (load (movimm tglobaladdr:$addr), GRP)>;

The patterns above should use tglobaladdr, because you will still need 
custom LowerGlobalAddress to generate them first, and it may need to 
attach special "target flags" to these addresses.

Finally, in LowerGlobalAddress, you can check the relocation model, 
compilation options, etc. to see if you need to have relocatable 
addresses, or not:

SDValue XSTGISelLowering::LowerGlobalAddress(SDValue Addr, SelectionDAG 
&DAG) {
   ...
   if (NeedGRP) {
     SpecialTargetFlags = ...;
     SDValue TAddr = DAG.getTargetGlobalAddress(..., SpecialTargetFlags);
     return DAG.getNode(XSTGISD::ADDR_USE_GRP, ..., TAddr);
   }

   // Non-relocatable address:
   SDValue NAddr = DAG.getTargetGlobalAddress(...);
   return DAG.getNode(XSTGISD::ADDR_NORMAL, ..., NAddr);
}


-Krzysztof

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation


More information about the llvm-dev mailing list