Markus Timpl
2014-Jan-28 23:30 UTC
[LLVMdev] Load Instruction that changes value of two registers
Hello, I'm writing a backend for an architecture that only has LOAD Instructions that first copy the old value of the target register in another register and after that load the provided value into the register. Example of an addition: load a, reg1; // -> copies old value of reg1 in reg2 and loads value from a into reg1 load b, reg1; // -> copies old value of reg1 in reg2 and loads value from b into reg1 add reg1, reg2; // adds values from a and b and saves the result into reg1 So I need to describe the "load X, reg1" Instruction so that LLVM understands it correctly. How can I do that in LLVM? Where is the best place to do that(TableGen, Instruction Selection, Instruction Lowering)? It would be fine if I could tell LLVM that reg2 is invalid after a load Operation, but I don#t know how to do that... I tried the following in TableGen to let LLVM know that Resg2 isn't valid anymore after a load but it didn't produce the desired result: let Defs = [Regs2] in { def LD: Inst<(outs Regs1:$dst), (ins MEM:$addr), "load $addr, $dst;", [(set Regs1:$dst, (load addr:$addr))]>; } Thanks in advance, Markus -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140129/2653ceba/attachment.html>
Quentin Colombet
2014-Jan-29 01:25 UTC
[LLVMdev] Load Instruction that changes value of two registers
Hi Markus, On Jan 28, 2014, at 3:30 PM, Markus Timpl <tima0900 at googlemail.com> wrote:> Hello, > I'm writing a backend for an architecture that only has LOAD Instructions that first copy the old value of the target register in another register and after that load the provided value into the register.If I understand correctly, your load performs in parallel a copy and a load: loadedVal<dstReg> load addr || <someReg> copy <dstReg> If you forget about the copy part, you can simply model your load like this: <dstReg>, <someReg> load addr <someReg> will be an implicit definition and your good to go. Obviously, this is not optimal. Note that, the original code (dot = load addr) does not define <someReg>, so I guess you have some rules to assign it (like <sameReg> = <dstReg> + 1). Therefore you may have to create a specific register class for that: <BigDstReg> load addr <dstReg> = BigDstReg.subIdx And have a pattern using a EXTRACT_SUBREG (see ARM NEON). Now, if you want to remember that <someReg> is not some trash value but contains the value of <dstReg> before this instruction, this is a different story. The tricky part here is how do you tell the compiler where does dstReg come from? Indeed, you will know that, only when you will choose it. You could make this choice a priori, but this is not optimal either. Anyhow, I do not think there is a straight answer for your case. Note: I was assuming that reg2 depends on the choice of reg1, if it is not the case, then, this is slightly a different story. -Quentin> > Example of an addition: > load a, reg1; // -> copies old value of reg1 in reg2 and loads value from a into reg1 > load b, reg1; // -> copies old value of reg1 in reg2 and loads value from b into reg1 > add reg1, reg2; // adds values from a and b and saves the result into reg1 > > So I need to describe the "load X, reg1" Instruction so that LLVM understands it correctly. > How can I do that in LLVM? Where is the best place to do that(TableGen, Instruction Selection, Instruction Lowering)? > > It would be fine if I could tell LLVM that reg2 is invalid after a load Operation, but I don#t know how to do that... > I tried the following in TableGen to let LLVM know that Resg2 isn't valid anymore after a load but it didn't produce the desired result: > > let Defs = [Regs2] in > { > def LD: Inst<(outs Regs1:$dst), (ins MEM:$addr), > > "load $addr, $dst;", > > [(set Regs1:$dst, (load addr:$addr))]>; > > } > > > Thanks in advance, > Markus > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140128/0ebdac68/attachment.html>
Markus Timpl
2014-Jan-29 03:49 UTC
[LLVMdev] Load Instruction that changes value of two registers
*Hello Quentin,** **thanks for the answer. Sadly I didn't completely get it.*> Hi Markus, > > On Jan 28, 2014, at 3:30 PM, Markus Timpl <tima0900 at googlemail.com > <mailto:tima0900 at googlemail.com>> wrote: > >> Hello, >> I'm writing a backend for an architecture that only has LOAD >> Instructions that first copy the old value of the target register in >> another register and after that load the provided value into the >> register. > If I understand correctly, your load performs in parallel a copy and a > load: > loadedVal<dstReg> load addr || <someReg> copy <dstReg>*Yes, it does exactly that. It first copies the old register value and then performs a "nomal" load.* *Let me give some more details about the target platform:** **It only has 2 useable registers(AKKU1 and AKKU2), it also has a status register but that doesn't matter in this case.** **It's only possible to directly load values into the AKKU1 register and each load into AKKU1 first copies the old AKKU1 value into AKKU2.** **The only way to get a value into AKKU2 is to first load it into AKKU1 and then copy it(can be done via another AKKU1 load or a copy instruction).* *There are possibilities to get a value into AKKU1/AKKU2 without changing the value of AKKU2/AKKU1 but they involve a couple of simple instructions and that's why I don't want to it that way(runtime of the code would be quite bad). *> > If you forget about the copy part, you can simply model your load like > this: > <dstReg>, <someReg> load addr > > <someReg> will be an implicit definition and your good to go. > Obviously, this is not optimal.*Do you mean a TableGen match pattern like this(AKKU1 and AKKU2 are register classes):** **[**(set (AKKU1:$dst, AKKU2:$dst2), (load addr:$addr))**]** ** **That obviously isn't a valid pattern...**So I don't understand how to put that into a valid pattern...** **Also wouldn't LLVM think that AKKU2 has the same value as AKKU1 after the operation and not a trash value?*> > Note that, the original code (dot = load addr) does not define > <someReg>, so I guess you have some rules to assign it (like <sameReg> > = <dstReg> + 1). > Therefore you may have to create a specific register class for that: > <BigDstReg> load addr > <dstReg> = BigDstReg.subIdx > And have a pattern using a EXTRACT_SUBREG (see ARM NEON). >*So <BigDstReg> will be AKKU1 and AKKU2, and I would do sth like that as match pattern: [(set (EXTRACT_SUBREG BigDestReg:$BigDestReg, 1), (load addr:$addr)] * *Is that correct? LLVM will assume that the other part of the register is trash after the instruction?*> > Now, if you want to remember that <someReg> is not some trash value > but contains the value of <dstReg> before this instruction, this is a > different story. > > The tricky part here is how do you tell the compiler where does dstReg > come from? Indeed, you will know that, only when you will choose it. > You could make this choice a priori, but this is not optimal either. > Anyhow, I do not think there is a straight answer for your case. > > Note: I was assuming that reg2 depends on the choice of reg1, if it is > not the case, then, this is slightly a different story. > > -Quentin >*Maybe it would be easier to take control of the DAG to MachineInstr step and arrange the instruction in a valid way? Do you think that is a good idea? The register allocation should be pretty easy with only two registers... Thanks again, Markus* -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140128/e3a6e1b6/attachment.html>