Hello, I am learning to write a new backend for LLVM and have a few simple questions. 1) What are the differences between 'constant' and 'targetconstant', 'globaladdress' and 'targetglobaladdress'? It is not clear from the document when and which should be used. 2) On the processor I am working on, there is a 'move reg, mem_addr' instruction. When I try to match it using the pattern [(set Int32Regs::reg, tglobaladdr::mem_addr)]. the code generated by tblgen cannot be compiled because there will be a switch statement that contains two cases for the 'tglobaladdr', one is hard-coded in by tblgen and the other is generated by tbglen following the pattern I specified. The compilation fails because of the two duplicated and conflicting cases. When I try to match it using the pattern [(set Int32Regs::reg, globaladdr::mem_addr)], the corresponding DAG node generated does not take the mem_addr as an input. As a matter of fact, it takes itself as an input and forms cycle. I am not sure if I explain the problems clearly. I can certainly provide more information if needed. Thank you in advance. P.B. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090419/bf2ef241/attachment.html>
On 20/04/2009, at 07.35, Peter Bacon wrote:> Hello, I am learning to write a new backend for LLVM and have a few > simple questions.Hi Peter, I am a newbie too, but I have recently dealt with the same issues.> 1) What are the differences between 'constant' and 'targetconstant', > 'globaladdress' and 'targetglobaladdress'? It is not clear from the > document when and which should be used.The target* variants are 'done' and will not be changed further by the instruction selection. After instruction selection, everything should be converted to the target* variants.> 2) On the processor I am working on, there is a 'move reg, mem_addr' > instruction. > > When I try to match it using the pattern [(set Int32Regs::reg, > tglobaladdr::mem_addr)]. the code generated by tblgen cannot be > compiled because there will be a switch statement that contains two > cases for the 'tglobaladdr', one is hard-coded in by tblgen and the > other is generated by tbglen following the pattern I specified. The > compilation fails because of the two duplicated and conflicting cases.This happened to me too. I stole a solution from the other targets - create a wrapper node: def BfinWrapper: SDNode<"BfinISD::Wrapper", SDTIntUnaryOp>; Then custom lower ISD::GlobalAddress, converting it to a wrapped TargetGlobalAddress: SDValue BlackfinTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { DebugLoc DL = Op.getDebugLoc(); GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); Op = DAG.getTargetGlobalAddress(GV, MVT::i32); return DAG.getNode(BfinISD::Wrapper, DL, MVT::i32, Op); } Now you can pattern match on the wrapper: def : Pat<(BfinWrapper (i32 tglobaladdr:$addr)), (LOAD32imm tglobaladdr:$addr)>; If you think this is overly complicated, I agree. Does anybody know why this is necessary? /jakob
Hi Jacob, thank you for your reply. Your suggestion works! But instead of using the Pat<>, I am using def MOVE_ADDR : MYInst<(outs Int32Regs:$dst), (ins i32mem:$a), "move $dst, $a;", [(set Int32Regs:$dst, (Wrapper tglobaladdr:$a))]>; I don't quite understand what the semantics of Pat in general. Could you please explain what def : Pat<(BfinWrapper (i32 tglobaladdr:$addr)), (LOAD32imm tglobaladdr:$addr)>; means? And I totally agree it would be better if someone can explain why the Wrapper is needed here. Regards, P.B. On Sun, Apr 19, 2009 at 11:01 PM, Jakob Stoklund Olesen <stoklund at 2pi.dk>wrote:> > On 20/04/2009, at 07.35, Peter Bacon wrote: > > > Hello, I am learning to write a new backend for LLVM and have a few > > simple questions. > > Hi Peter, > > I am a newbie too, but I have recently dealt with the same issues. > > > 1) What are the differences between 'constant' and 'targetconstant', > > 'globaladdress' and 'targetglobaladdress'? It is not clear from the > > document when and which should be used. > > The target* variants are 'done' and will not be changed further by the > instruction selection. After instruction selection, everything should > be converted to the target* variants. > > > 2) On the processor I am working on, there is a 'move reg, mem_addr' > > instruction. > > > > When I try to match it using the pattern [(set Int32Regs::reg, > > tglobaladdr::mem_addr)]. the code generated by tblgen cannot be > > compiled because there will be a switch statement that contains two > > cases for the 'tglobaladdr', one is hard-coded in by tblgen and the > > other is generated by tbglen following the pattern I specified. The > > compilation fails because of the two duplicated and conflicting cases. > > This happened to me too. I stole a solution from the other targets - > create a wrapper node: > > def BfinWrapper: SDNode<"BfinISD::Wrapper", SDTIntUnaryOp>; > > Then custom lower ISD::GlobalAddress, converting it to a wrapped > TargetGlobalAddress: > > SDValue > BlackfinTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG > &DAG) > { > DebugLoc DL = Op.getDebugLoc(); > GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); > > Op = DAG.getTargetGlobalAddress(GV, MVT::i32); > return DAG.getNode(BfinISD::Wrapper, DL, MVT::i32, Op); > } > > Now you can pattern match on the wrapper: > > def : Pat<(BfinWrapper (i32 tglobaladdr:$addr)), > (LOAD32imm tglobaladdr:$addr)>; > > If you think this is overly complicated, I agree. > Does anybody know why this is necessary? > > /jakob > > _______________________________________________ > 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/20090420/7210538e/attachment.html>