After discussions last night, I'm leaning towards going legit with all my pseudo expansions in Mips 16. Some I think I can clearly do by just putting in the proper side effects of implicit registers (T8 the condition code register as used by mips 16). But I'm still left with some pseudos that have jmp .+4 type instructions in them. The original Mips port was to Mips I and Mips I, like Mips 16, has no conditional store instructions. There was some super ugly code there to do a test and then branch around the store instruction if the test was not matched. It was quite a large amount of code and I'm not sure I even believe it works. It's long been commented out since we don't even support Mips I anymore. I avoided that in Mips 16 by writing some patterns that translate to something like: cmp rx, ry ; implicitly set T8 btnez foo: ; branch if T8 not zero mov ra, rb foo:.... There is a way to do this in Mips asembler without needing to really create a label. There are builtin forward and backward labels you can use for this and that's what I do in some cases and in other cases I think I just do a .+4 or something. SOmething like that. You can see the mips 16 patterns if you want to know the details but they are not important here IMO. In principle I should really make machine basic blocks and do all that book keeping but at least the original way is way too complicated and as I said, I'm not sure I believe it even works in all cases. Too many complex assumptions about the optimizer and such. Any ideas or code pointers for creating the kind of machine basic blocks I would need to do the above without resorting to bundles? I like simple. Simple usually works always and complex always has at least one more bug. :) Tia. Reed
This is the old MIPS I code that sort of does what I need to do. This seems really involved to do such a simple thing. Maybe there are now helper classes for this or some better example I can look at. I suppose I can mimick this if people say this just the correct way to do this in LLVM. static MachineBasicBlock* ExpandCondMov(MachineInstr *MI, MachineBasicBlock *BB, DebugLoc dl, const MipsSubtarget *Subtarget, const TargetInstrInfo *TII, bool isFPCmp, unsigned Opc) { // There is no need to expand CMov instructions if target has // conditional moves. if (Subtarget->hasCondMov()) return BB; // To "insert" a SELECT_CC instruction, we actually have to insert the // diamond control-flow pattern. The incoming instruction knows the // destination vreg to set, the condition code register to branch on, the // true/false values to select between, and a branch opcode to use. const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator It = BB; ++It; // thisMBB: // ... // TrueVal = ... // setcc r1, r2, r3 // bNE r1, r0, copy1MBB // fallthrough --> copy0MBB MachineBasicBlock *thisMBB = BB; MachineFunction *F = BB->getParent(); MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); F->insert(It, copy0MBB); F->insert(It, sinkMBB); // Transfer the remainder of BB and its successor edges to sinkMBB. sinkMBB->splice(sinkMBB->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), BB->end()); sinkMBB->transferSuccessorsAndUpdatePHIs(BB); // Next, add the true and fallthrough blocks as its successors. BB->addSuccessor(copy0MBB); BB->a On 02/17/2013 12:51 PM, Reed Kotler wrote:> After discussions last night, I'm leaning towards going legit with all > my pseudo expansions in Mips 16. > > Some I think I can clearly do by just putting in the proper side effects > of implicit registers (T8 the condition code register as used by mips 16). > > But I'm still left with some pseudos that have jmp .+4 type instructions > in them. > > The original Mips port was to Mips I and Mips I, like Mips 16, has no > conditional store instructions. > > There was some super ugly code there to do a test and then branch around > the store instruction if the test was not matched. It was quite a large > amount of code and I'm not sure I even believe it works. It's long been > commented out since we don't even support Mips I anymore. > > I avoided that in Mips 16 by writing some patterns that translate to > something like: > > cmp rx, ry ; implicitly set T8 > btnez foo: ; branch if T8 not zero > mov ra, rb > foo:.... > > There is a way to do this in Mips asembler without needing to really > create a label. There are builtin forward and backward labels you can > use for this and that's what I do in some cases and in other cases I > think I just do a .+4 or something. > > SOmething like that. You can see the mips 16 patterns if you want to > know the details but they are not important here IMO. > > In principle I should really make machine basic blocks and do all that > book keeping but at least the original way is way too complicated and as > I said, I'm not sure I believe it even works in all cases. Too many > complex assumptions about the optimizer and such. > > Any ideas or code pointers for creating the kind of machine basic blocks > I would need to do the above without resorting to bundles? > > I like simple. > > Simple usually works always and complex always has at least one more > bug. :) > > Tia. > > Reed
Some stuff did not get pasted in properly. static MachineBasicBlock* ExpandCondMov(MachineInstr *MI, MachineBasicBlock *BB, DebugLoc dl, const MipsSubtarget *Subtarget, const TargetInstrInfo *TII, bool isFPCmp, unsigned Opc) { // There is no need to expand CMov instructions if target has // conditional moves. if (Subtarget->hasCondMov()) return BB; // To "insert" a SELECT_CC instruction, we actually have to insert the // diamond control-flow pattern. The incoming instruction knows the // destination vreg to set, the condition code register to branch on, the // true/false values to select between, and a branch opcode to use. const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator It = BB; ++It; // thisMBB: // ... // TrueVal = ... // setcc r1, r2, r3 // bNE r1, r0, copy1MBB // fallthrough --> copy0MBB MachineBasicBlock *thisMBB = BB; MachineFunction *F = BB->getParent(); MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); F->insert(It, copy0MBB); F->insert(It, sinkMBB); // Transfer the remainder of BB and its successor edges to sinkMBB. sinkMBB->splice(sinkMBB->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), BB->end()); sinkMBB->transferSuccessorsAndUpdatePHIs(BB); // Next, add the true and fallthrough blocks as its successors. BB->addSuccessor(copy0MBB); BB->addSuccessor(sinkMBB); // Emit the right instruction according to the type of the operands compared if (isFPCmp) BuildMI(BB, dl, TII->get(Opc)).addMBB(sinkMBB); else BuildMI(BB, dl, TII->get(Opc)).addReg(MI->getOperand(2).getReg()) .addReg(Mips::ZERO).addMBB(sinkMBB); // copy0MBB: // %FalseValue = ... // # fallthrough to sinkMBB BB = copy0MBB; // Update machine-CFG edges BB->addSuccessor(sinkMBB); // sinkMBB: // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ] // ... BB = sinkMBB; if (isFPCmp) BuildMI(*BB, BB->begin(), dl, TII->get(Mips::PHI), MI->getOperand(0).getReg()) .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB) .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB); else BuildMI(*BB, BB->begin(), dl, TII->get(Mips::PHI), MI->getOperand(0).getReg()) .addReg(MI->getOperand(3).getReg()).addMBB(thisMBB) .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB); MI->eraseFromParent(); // The pseudo instruction is gone now. return BB; } On 02/17/2013 04:45 PM, Reed Kotler wrote:> This is the old MIPS I code that sort of does what I need to do. This > seems really involved to do such a simple thing. > > Maybe there are now helper classes for this or some better example I can > look at. I suppose I can mimick this if people say this just the correct > way to do this in LLVM. > > static MachineBasicBlock* ExpandCondMov(MachineInstr *MI, > MachineBasicBlock *BB, > DebugLoc dl, > const MipsSubtarget *Subtarget, > const TargetInstrInfo *TII, > bool isFPCmp, unsigned Opc) { > // There is no need to expand CMov instructions if target has > // conditional moves. > if (Subtarget->hasCondMov()) > return BB; > > // To "insert" a SELECT_CC instruction, we actually have to insert the > // diamond control-flow pattern. The incoming instruction knows the > // destination vreg to set, the condition code register to branch on, > the > // true/false values to select between, and a branch opcode to use. > const BasicBlock *LLVM_BB = BB->getBasicBlock(); > MachineFunction::iterator It = BB; > ++It; > > // thisMBB: > // ... > // TrueVal = ... > // setcc r1, r2, r3 > // bNE r1, r0, copy1MBB > // fallthrough --> copy0MBB > MachineBasicBlock *thisMBB = BB; > MachineFunction *F = BB->getParent(); > MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); > MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); > F->insert(It, copy0MBB); > F->insert(It, sinkMBB); > > // Transfer the remainder of BB and its successor edges to sinkMBB. > sinkMBB->splice(sinkMBB->begin(), BB, > llvm::next(MachineBasicBlock::iterator(MI)), > BB->end()); > sinkMBB->transferSuccessorsAndUpdatePHIs(BB); > > // Next, add the true and fallthrough blocks as its successors. > BB->addSuccessor(copy0MBB); > BB->a > On 02/17/2013 12:51 PM, Reed Kotler wrote: >> After discussions last night, I'm leaning towards going legit with all >> my pseudo expansions in Mips 16. >> >> Some I think I can clearly do by just putting in the proper side effects >> of implicit registers (T8 the condition code register as used by mips >> 16). >> >> But I'm still left with some pseudos that have jmp .+4 type instructions >> in them. >> >> The original Mips port was to Mips I and Mips I, like Mips 16, has no >> conditional store instructions. >> >> There was some super ugly code there to do a test and then branch around >> the store instruction if the test was not matched. It was quite a large >> amount of code and I'm not sure I even believe it works. It's long been >> commented out since we don't even support Mips I anymore. >> >> I avoided that in Mips 16 by writing some patterns that translate to >> something like: >> >> cmp rx, ry ; implicitly set T8 >> btnez foo: ; branch if T8 not zero >> mov ra, rb >> foo:.... >> >> There is a way to do this in Mips asembler without needing to really >> create a label. There are builtin forward and backward labels you can >> use for this and that's what I do in some cases and in other cases I >> think I just do a .+4 or something. >> >> SOmething like that. You can see the mips 16 patterns if you want to >> know the details but they are not important here IMO. >> >> In principle I should really make machine basic blocks and do all that >> book keeping but at least the original way is way too complicated and as >> I said, I'm not sure I believe it even works in all cases. Too many >> complex assumptions about the optimizer and such. >> >> Any ideas or code pointers for creating the kind of machine basic blocks >> I would need to do the above without resorting to bundles? >> >> I like simple. >> >> Simple usually works always and complex always has at least one more >> bug. :) >> >> Tia. >> >> Reed
Reed, Have a look at custom inserters. In particular, how they're used for atomics in the ARM backend. -Jim On Feb 17, 2013, at 12:51 PM, Reed Kotler <rkotler at mips.com> wrote:> After discussions last night, I'm leaning towards going legit with all my pseudo expansions in Mips 16. > > Some I think I can clearly do by just putting in the proper side effects of implicit registers (T8 the condition code register as used by mips 16). > > But I'm still left with some pseudos that have jmp .+4 type instructions in them. > > The original Mips port was to Mips I and Mips I, like Mips 16, has no conditional store instructions. > > There was some super ugly code there to do a test and then branch around the store instruction if the test was not matched. It was quite a large amount of code and I'm not sure I even believe it works. It's long been commented out since we don't even support Mips I anymore. > > I avoided that in Mips 16 by writing some patterns that translate to something like: > > cmp rx, ry ; implicitly set T8 > btnez foo: ; branch if T8 not zero > mov ra, rb > foo:.... > > There is a way to do this in Mips asembler without needing to really create a label. There are builtin forward and backward labels you can use for this and that's what I do in some cases and in other cases I think I just do a .+4 or something. > > SOmething like that. You can see the mips 16 patterns if you want to know the details but they are not important here IMO. > > In principle I should really make machine basic blocks and do all that book keeping but at least the original way is way too complicated and as I said, I'm not sure I believe it even works in all cases. Too many > complex assumptions about the optimizer and such. > > Any ideas or code pointers for creating the kind of machine basic blocks I would need to do the above without resorting to bundles? > > I like simple. > > Simple usually works always and complex always has at least one more bug. :) > > Tia. > > Reed > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On 02/18/2013 11:34 AM, Jim Grosbach wrote:> Reed, > > Have a look at custom inserters. In particular, how they're used for atomics in the ARM backend. > > -JimNice. I see that we are using them in the Mips backend (probably copied from the Arm backend) but I did not work on that code so never paid attention to what that was about. I think I can insert my expansions right there and not have to put them into any post isel phases and such.> On Feb 17, 2013, at 12:51 PM, Reed Kotler <rkotler at mips.com> wrote: > >> After discussions last night, I'm leaning towards going legit with all my pseudo expansions in Mips 16. >> >> Some I think I can clearly do by just putting in the proper side effects of implicit registers (T8 the condition code register as used by mips 16). >> >> But I'm still left with some pseudos that have jmp .+4 type instructions in them. >> >> The original Mips port was to Mips I and Mips I, like Mips 16, has no conditional store instructions. >> >> There was some super ugly code there to do a test and then branch around the store instruction if the test was not matched. It was quite a large amount of code and I'm not sure I even believe it works. It's long been commented out since we don't even support Mips I anymore. >> >> I avoided that in Mips 16 by writing some patterns that translate to something like: >> >> cmp rx, ry ; implicitly set T8 >> btnez foo: ; branch if T8 not zero >> mov ra, rb >> foo:.... >> >> There is a way to do this in Mips asembler without needing to really create a label. There are builtin forward and backward labels you can use for this and that's what I do in some cases and in other cases I think I just do a .+4 or something. >> >> SOmething like that. You can see the mips 16 patterns if you want to know the details but they are not important here IMO. >> >> In principle I should really make machine basic blocks and do all that book keeping but at least the original way is way too complicated and as I said, I'm not sure I believe it even works in all cases. Too many >> complex assumptions about the optimizer and such. >> >> Any ideas or code pointers for creating the kind of machine basic blocks I would need to do the above without resorting to bundles? >> >> I like simple. >> >> Simple usually works always and complex always has at least one more bug. :) >> >> Tia. >> >> Reed >> >> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Maybe Matching Threads
- [LLVMdev] splitting a branch within a pseudo
- [LLVMdev] Implementing llvm.atomic.cmp.swap.i32 on PowerPC
- [LLVMdev] splitting a branch within a pseudo
- [LLVMdev] Implementing llvm.atomic.cmp.swap.i32 on PowerPC
- [LLVMdev] Implementing llvm.atomic.cmp.swap.i32 on PowerPC