Steve Montgomery
2012-Nov-24 17:23 UTC
[LLVMdev] Fwd: Prevention register promotion at the isel codegen phase
Sorry, forgot to Reply-All. Begin forwarded message:> From: Steve Montgomery <stephen.montgomery3 at btinternet.com> > Subject: Re: [LLVMdev] Prevention register promotion at the isel codegen phase > Date: 24 November 2012 17:09:58 GMT > To: Joseph Pusdesris <joe at pusdesris.com> > > I had a similar problem trying to implement reg-mem operations. The solution I chose was to use PreprocessISelDAG() to decide which operands needed spilling to memory and then to store and load them from a new stack slot. This seems to work OK for me, though I'm no expert in such matters - perhaps someone more knowledgeable could comment? > > Given that operand OpNo of Node needs to be a load, this is the code snippet I used: > > // Now we know which node to spill, perform the spill. > SDValue SpillVal = Node->getOperand(OpNo); > SDValue SpillSlot = CurDAG->CreateStackTemporary(SpillVal.getValueType()); > int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex(); > SDValue Chain = CurDAG->getStore(CurDAG->getEntryNode(), > SpillVal.getDebugLoc(), > SpillVal, SpillSlot, > MachinePointerInfo::getFixedStack(FI), > false, false, 0); > Chain = CurDAG->getLoad(SpillVal.getValueType(), SpillVal.getDebugLoc(), > Chain, SpillSlot, > MachinePointerInfo::getFixedStack(FI), > false, false, false, 0); > > SmallVector<SDValue, 4> Ops; > unsigned NumOps = Node->getNumOperands(); > > for (unsigned i = 0; i < NumOps; ++i) { > if (i == OpNo) > Ops.push_back(Chain); > else > Ops.push_back(Node->getOperand(i)); > } > > CurDAG->UpdateNodeOperands(Node, &Ops[0], NumOps); > > Note: you can't do this during ISelLowering because the combiner will just remove the store and load again unless you mark one or the other as volatile and that doesn't seem like the right thing to do. > > Hope that helps. > > On 23 Nov 2012, at 18:02, Joseph Pusdesris wrote: > >> I am trying to implement mem-mem operations, but I can't seem to figure out how to prevent register promotion for most cases. >> >> I can successfully compile: >> int foo(int a, int b){ >> return a + b; >> } >> >> because it gets matched to store(add(load)(load)), but when I attempt to compile: >> int foo(int a, int b, int c){ >> return a + b + c; >> } >> >> I can't match the add anymore since it is of the form store(add(add(load)(load))(load)). I think I need to figure out how to force a load/store between the two adds. I am not sure where to load/store to though, I need to allocate a spill location or something I assume. >> >> Any insight would be greatly appreciated. >> _______________________________________________ >> 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/20121124/e905bf2b/attachment.html>
Joseph Pusdesris
2012-Nov-24 17:27 UTC
[LLVMdev] Fwd: Prevention register promotion at the isel codegen phase
Yes, this is very helpful! Thank you! How does this work when exiting a variable's liveness range? Will it automatically know to free the stack slot for reuse? -Joe On Sat, Nov 24, 2012 at 12:23 PM, Steve Montgomery < stephen.montgomery3 at btinternet.com> wrote:> Sorry, forgot to Reply-All. > > Begin forwarded message: > > *From: *Steve Montgomery <stephen.montgomery3 at btinternet.com> > *Subject: **Re: [LLVMdev] Prevention register promotion at the isel > codegen phase* > *Date: *24 November 2012 17:09:58 GMT > *To: *Joseph Pusdesris <joe at pusdesris.com> > > I had a similar problem trying to implement reg-mem operations. The > solution I chose was to use PreprocessISelDAG() to decide which operands > needed spilling to memory and then to store and load them from a new stack > slot. This seems to work OK for me, though I'm no expert in such matters - > perhaps someone more knowledgeable could comment? > > Given that operand OpNo of Node needs to be a load, this is the code > snippet I used: > > // Now we know which node to spill, perform the spill. > SDValue SpillVal = Node->getOperand(OpNo); > SDValue SpillSlot = CurDAG->CreateStackTemporary(SpillVal.getValueType()); > int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex(); > SDValue Chain = CurDAG->getStore(CurDAG->getEntryNode(), > SpillVal.getDebugLoc(), > SpillVal, SpillSlot, > > MachinePointerInfo::getFixedStack(FI), > false, false, 0); > Chain = CurDAG->getLoad(SpillVal.getValueType(), SpillVal.getDebugLoc(), > Chain, SpillSlot, > MachinePointerInfo::getFixedStack(FI), > false, false, false, 0); > > SmallVector<SDValue, 4> Ops; > unsigned NumOps = Node->getNumOperands(); > > for (unsigned i = 0; i < NumOps; ++i) { > if (i == OpNo) > Ops.push_back(Chain); > else > Ops.push_back(Node->getOperand(i)); > } > > CurDAG->UpdateNodeOperands(Node, &Ops[0], NumOps); > > Note: you can't do this during ISelLowering because the combiner will just > remove the store and load again unless you mark one or the other as > volatile and that doesn't seem like the right thing to do. > > Hope that helps. > > On 23 Nov 2012, at 18:02, Joseph Pusdesris wrote: > > I am trying to implement mem-mem operations, but I can't seem to figure > out how to prevent register promotion for most cases. > > > I can successfully compile: > > int foo(int a, int b){ > > return a + b; > > } > > > because it gets matched to store(add(load)(load)), but when I attempt to > compile: > > int foo(int a, int b, int c){ > > return a + b + c; > > } > > > I can't match the add anymore since it is of the form > store(add(add(load)(load))(load)). I think I need to figure out how to > force a load/store between the two adds. I am not sure where to load/store > to though, I need to allocate a spill location or something I assume. > > > Any insight would be greatly appreciated. > > _______________________________________________ > > LLVM Developers mailing list > > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > > > > _______________________________________________ > 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/20121124/117e9e90/attachment.html>
Steve Montgomery
2012-Nov-24 18:49 UTC
[LLVMdev] Fwd: Prevention register promotion at the isel codegen phase
The stack temporaries are allocated to physical stack slots after register allocation, I believe, so yes they will be reused automatically when possible. On 24 Nov 2012, at 17:27, Joseph Pusdesris wrote:> Yes, this is very helpful! Thank you! > > How does this work when exiting a variable's liveness range? Will it automatically know to free the stack slot for reuse? > -Joe > > > On Sat, Nov 24, 2012 at 12:23 PM, Steve Montgomery <stephen.montgomery3 at btinternet.com> wrote: > Sorry, forgot to Reply-All. > > Begin forwarded message: > >> From: Steve Montgomery <stephen.montgomery3 at btinternet.com> >> Subject: Re: [LLVMdev] Prevention register promotion at the isel codegen phase >> Date: 24 November 2012 17:09:58 GMT >> To: Joseph Pusdesris <joe at pusdesris.com> >> >> I had a similar problem trying to implement reg-mem operations. The solution I chose was to use PreprocessISelDAG() to decide which operands needed spilling to memory and then to store and load them from a new stack slot. This seems to work OK for me, though I'm no expert in such matters - perhaps someone more knowledgeable could comment? >> >> Given that operand OpNo of Node needs to be a load, this is the code snippet I used: >> >> // Now we know which node to spill, perform the spill. >> SDValue SpillVal = Node->getOperand(OpNo); >> SDValue SpillSlot = CurDAG->CreateStackTemporary(SpillVal.getValueType()); >> int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex(); >> SDValue Chain = CurDAG->getStore(CurDAG->getEntryNode(), >> SpillVal.getDebugLoc(), >> SpillVal, SpillSlot, >> MachinePointerInfo::getFixedStack(FI), >> false, false, 0); >> Chain = CurDAG->getLoad(SpillVal.getValueType(), SpillVal.getDebugLoc(), >> Chain, SpillSlot, >> MachinePointerInfo::getFixedStack(FI), >> false, false, false, 0); >> >> SmallVector<SDValue, 4> Ops; >> unsigned NumOps = Node->getNumOperands(); >> >> for (unsigned i = 0; i < NumOps; ++i) { >> if (i == OpNo) >> Ops.push_back(Chain); >> else >> Ops.push_back(Node->getOperand(i)); >> } >> >> CurDAG->UpdateNodeOperands(Node, &Ops[0], NumOps); >> >> Note: you can't do this during ISelLowering because the combiner will just remove the store and load again unless you mark one or the other as volatile and that doesn't seem like the right thing to do. >> >> Hope that helps. >> >> On 23 Nov 2012, at 18:02, Joseph Pusdesris wrote: >> >>> I am trying to implement mem-mem operations, but I can't seem to figure out how to prevent register promotion for most cases. >>> >>> I can successfully compile: >>> int foo(int a, int b){ >>> return a + b; >>> } >>> >>> because it gets matched to store(add(load)(load)), but when I attempt to compile: >>> int foo(int a, int b, int c){ >>> return a + b + c; >>> } >>> >>> I can't match the add anymore since it is of the form store(add(add(load)(load))(load)). I think I need to figure out how to force a load/store between the two adds. I am not sure where to load/store to though, I need to allocate a spill location or something I assume. >>> >>> Any insight would be greatly appreciated. >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> > > > _______________________________________________ > 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/20121124/2c352557/attachment.html>
Apparently Analagous Threads
- [LLVMdev] Fwd: Prevention register promotion at the isel codegen phase
- [LLVMdev] Splitting a load with 2 consumers into 2 loads.
- [LLVMdev] Splitting a load with 2 consumers into 2 loads.
- [LLVMdev] Splitting a load with 2 consumers into 2 loads.
- [LLVMdev] Splitting a load with 2 consumers into 2 loads.