[llvm-commits] [llvm] r47593 - in /llvm/trunk/lib/Target/X86: X86ISelLowering.cpp X86ISelLowering.h
Arnold Schwaighofer
arnold.schwaighofer at gmail.com
Tue Feb 26 09:46:40 PST 2008
Will correct. I always get them wrong. actually looked before
commiting and many functions in that file had 2 so i followed :).
On 26 Feb 2008, at 18:24, Tanya Lattner wrote:
> Please use doxygen style comments for functions (///)
>
> -Tanya
>
> On Feb 26, 2008, at 1:20 AM, Arnold Schwaighofer wrote:
>
>> Author: arnolds
>> Date: Tue Feb 26 03:19:59 2008
>> New Revision: 47593
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=47593&view=rev
>> Log:
>> Change the lowering of arguments for tail call optimized
>> calls. Before arguments that could overwrite each other were
>> explicitly lowered to a stack slot, not giving the register allocator
>> a chance to optimize. Now a sequence of copyto/copyfrom virtual
>> registers ensures that arguments are loaded in (virtual) registers
>> before they are lowered to the stack slot (and might overwrite each
>> other). Also parameter stack slots are marked mutable for
>> (potentially) tail calling functions.
>>
>> Modified:
>> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>> llvm/trunk/lib/Target/X86/X86ISelLowering.h
>>
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/
>> X86ISelLowering.cpp?rev=47593&r1=47592&r2=47593&view=diff
>>
>> =====================================================================
>> =
>> ========
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Feb 26
>> 03:19:59 2008
>> @@ -1057,26 +1057,55 @@
>> return None;
>> }
>>
>> -
>> // IsPossiblyOverwrittenArgumentOfTailCall - Check if the operand
>> could possibly
>> // be overwritten when lowering the outgoing arguments in a tail
>> call. Currently
>> // the implementation of this call is very conservative and
>> assumes all
>> // arguments sourcing from FORMAL_ARGUMENTS or a CopyFromReg with
>> virtual
>> // registers would be overwritten by direct lowering.
>> -// Possible improvement:
>> -// Check FORMAL_ARGUMENTS corresponding MERGE_VALUES for
>> CopyFromReg nodes
>> -// indicating inreg passed arguments which also need not be
>> lowered to a safe
>> -// stack slot.
>> -static bool IsPossiblyOverwrittenArgumentOfTailCall(SDOperand Op) {
>> +static bool IsPossiblyOverwrittenArgumentOfTailCall(SDOperand Op,
>> +
>> MachineFrameInfo * MFI) {
>> RegisterSDNode * OpReg = NULL;
>> + FrameIndexSDNode * FrameIdxNode = NULL;
>> + int FrameIdx = 0;
>> if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS ||
>> (Op.getOpcode()== ISD::CopyFromReg &&
>> - (OpReg = cast<RegisterSDNode>(Op.getOperand(1))) &&
>> - OpReg->getReg() >= TargetRegisterInfo::FirstVirtualRegister))
>> + (OpReg = dyn_cast<RegisterSDNode>(Op.getOperand(1))) &&
>> + (OpReg->getReg() >=
>> TargetRegisterInfo::FirstVirtualRegister)) ||
>> + (Op.getOpcode() == ISD::LOAD &&
>> + (FrameIdxNode = dyn_cast<FrameIndexSDNode>(Op.getOperand
>> (1))) &&
>> + (MFI->isFixedObjectIndex((FrameIdx = FrameIdxNode->getIndex
>> ()))) &&
>> + (MFI->getObjectOffset(FrameIdx) >= 0)))
>> return true;
>> return false;
>> }
>>
>> +// CopyTailCallClobberedArgumentsToVRegs - Create virtual
>> registers for all
>> +// arguments to force loading and guarantee that arguments
>> sourcing from
>> +// incomming parameters are not overwriting each other.
>> +static SDOperand
>> +CopyTailCallClobberedArgumentsToVRegs(SDOperand Chain,
>> + SmallVector<std::pair<unsigned, SDOperand>, 8>
>> &TailCallClobberedVRegs,
>> + SelectionDAG &DAG,
>> + MachineFunction &MF,
>> + const TargetLowering * TL) {
>> +
>> + SDOperand InFlag;
>> + for (unsigned i = 0, e = TailCallClobberedVRegs.size(); i != e; i
>> ++) {
>> + SDOperand Arg = TailCallClobberedVRegs[i].second;
>> + unsigned Idx = TailCallClobberedVRegs[i].first;
>> + unsigned VReg =
>> + MF.getRegInfo().
>> + createVirtualRegister(TL->getRegClassFor(Arg.getValueType()));
>> + Chain = DAG.getCopyToReg(Chain, VReg, Arg, InFlag);
>> + InFlag = Chain.getValue(1);
>> + Arg = DAG.getCopyFromReg(Chain, VReg, Arg.getValueType(),
>> InFlag);
>> + TailCallClobberedVRegs[i] = std::make_pair(Idx, Arg);
>> + Chain = Arg.getValue(1);
>> + InFlag = Arg.getValue(2);
>> + }
>> + return Chain;
>> +}
>> +
>> // CreateCopyOfByValArgument - Make a copy of an aggregate at
>> address specified
>> // by "Src" to address "Dst" with size and alignment information
>> specified by
>> // the specific parameter attribute. The copy will be passed as a
>> byval function
>> @@ -1097,15 +1126,20 @@
>> SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op,
>> SelectionDAG &DAG,
>> const CCValAssign &VA,
>> MachineFrameInfo *MFI,
>> + unsigned CC,
>> SDOperand Root,
>> unsigned i) {
>> // Create the nodes corresponding to a load from this parameter
>> slot.
>> unsigned Flags = cast<ConstantSDNode>(Op.getOperand(3 + i))-
>>> getValue();
>> + bool AlwaysUseMutable = (CC==CallingConv::Fast) &&
>> PerformTailCallOpt;
>> bool isByVal = Flags & ISD::ParamFlags::ByVal;
>> + bool isImmutable = !AlwaysUseMutable && !isByVal;
>>
>> - // FIXME: For now, all byval parameter objects are marked
>> mutable. This
>> - // can be changed with more analysis.
>> + // FIXME: For now, all byval parameter objects are marked
>> mutable. This can be
>> + // changed with more analysis.
>> + // In case of tail call optimization mark all arguments mutable.
>> Since they
>> + // could be overwritten by lowering of arguments in case of a
>> tail call.
>> int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT
>> ())/8,
>> - VA.getLocMemOffset(), !isByVal);
>> + VA.getLocMemOffset(),
>> isImmutable);
>> SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
>> if (isByVal)
>> return FIN;
>> @@ -1195,7 +1229,7 @@
>> ArgValues.push_back(ArgValue);
>> } else {
>> assert(VA.isMemLoc());
>> - ArgValues.push_back(LowerMemArgument(Op, DAG, VA, MFI, Root,
>> i));
>> + ArgValues.push_back(LowerMemArgument(Op, DAG, VA, MFI, CC,
>> Root, i));
>> }
>> }
>>
>> @@ -1381,6 +1415,7 @@
>>
>> SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG
>> &DAG) {
>> MachineFunction &MF = DAG.getMachineFunction();
>> + MachineFrameInfo * MFI = MF.getFrameInfo();
>> SDOperand Chain = Op.getOperand(0);
>> unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))-
>>> getValue();
>> bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))-
>>> getValue() != 0;
>> @@ -1442,7 +1477,7 @@
>>
>> Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant
>> (NumBytes));
>>
>> - SDOperand RetAddrFrIdx, NewRetAddrFrIdx;
>> + SDOperand RetAddrFrIdx;
>> if (IsTailCall) {
>> // Adjust the Return address stack slot.
>> if (FPDiff) {
>> @@ -1451,23 +1486,18 @@
>> // Load the "old" Return address.
>> RetAddrFrIdx =
>> DAG.getLoad(VT, Chain,RetAddrFrIdx, NULL, 0);
>> - // Calculate the new stack slot for the return address.
>> - int SlotSize = Is64Bit ? 8 : 4;
>> - int NewReturnAddrFI =
>> - MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-
>> SlotSize);
>> - NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
>> Chain = SDOperand(RetAddrFrIdx.Val, 1);
>> }
>> }
>>
>> SmallVector<std::pair<unsigned, SDOperand>, 8> RegsToPass;
>> + SmallVector<std::pair<unsigned, SDOperand>, 8>
>> TailCallClobberedVRegs;
>> SmallVector<SDOperand, 8> MemOpChains;
>>
>> SDOperand StackPtr;
>>
>> // Walk the register/memloc assignments, inserting copies/
>> loads. For tail
>> - // calls, lower arguments which could otherwise be possibly
>> overwritten to the
>> - // stack slot where they would go on normal function calls.
>> + // calls, remember all arguments for later special lowering.
>> for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
>> CCValAssign &VA = ArgLocs[i];
>> SDOperand Arg = Op.getOperand(5+2*VA.getValNo());
>> @@ -1490,13 +1520,15 @@
>> if (VA.isRegLoc()) {
>> RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
>> } else {
>> - if (!IsTailCall || IsPossiblyOverwrittenArgumentOfTailCall
>> (Arg)) {
>> + if (!IsTailCall) {
>> assert(VA.isMemLoc());
>> if (StackPtr.Val == 0)
>> StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr,
>> getPointerTy());
>>
>> MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr,
>> VA, Chain,
>> Arg));
>> + } else if (IsPossiblyOverwrittenArgumentOfTailCall(Arg,
>> MFI)) {
>> + TailCallClobberedVRegs.push_back(std::make_pair(i,Arg));
>> }
>> }
>> }
>> @@ -1514,9 +1546,6 @@
>> InFlag = Chain.getValue(1);
>> }
>>
>> - if (IsTailCall)
>> - InFlag = SDOperand(); // ??? Isn't this nuking the preceding
>> loop's output?
>> -
>> // ELF / PIC requires GOT in the EBX register before function
>> calls via PLT
>> // GOT pointer.
>> // Does not work with tail call since ebx is not restored
>> correctly by
>> @@ -1551,11 +1580,18 @@
>> InFlag = Chain.getValue(1);
>> }
>>
>> +
>> // For tail calls lower the arguments to the 'real' stack slot.
>> if (IsTailCall) {
>> SmallVector<SDOperand, 8> MemOpChains2;
>> SDOperand FIN;
>> int FI = 0;
>> + // Do not flag preceeding copytoreg stuff together with the
>> following stuff.
>> + InFlag = SDOperand();
>> +
>> + Chain = CopyTailCallClobberedArgumentsToVRegs(Chain,
>> TailCallClobberedVRegs,
>> + DAG, MF, this);
>> +
>> for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
>> CCValAssign &VA = ArgLocs[i];
>> if (!VA.isRegLoc()) {
>> @@ -1568,28 +1604,26 @@
>> uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8;
>> FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset);
>> FIN = DAG.getFrameIndex(FI, MVT::i32);
>> - SDOperand Source = Arg;
>> - if (IsPossiblyOverwrittenArgumentOfTailCall(Arg)) {
>> - // Copy from stack slots to stack slot of a tail called
>> function. This
>> - // needs to be done because if we would lower the
>> arguments directly
>> - // to their real stack slot we might end up overwriting
>> each other.
>> - // Get source stack slot.
>> - Source = DAG.getIntPtrConstant(VA.getLocMemOffset());
>> - if (StackPtr.Val == 0)
>> - StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr,
>> getPointerTy());
>> - Source = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr,
>> Source);
>> - if ((Flags & ISD::ParamFlags::ByVal)==0)
>> - Source = DAG.getLoad(VA.getValVT(), Chain, Source,
>> NULL, 0);
>> - }
>>
>> + // Find virtual register for this argument.
>> + bool Found=false;
>> + for (unsigned idx=0, e= TailCallClobberedVRegs.size(); idx
>> < e; idx++)
>> + if (TailCallClobberedVRegs[idx].first==i) {
>> + Arg = TailCallClobberedVRegs[idx].second;
>> + Found=true;
>> + break;
>> + }
>> + assert(IsPossiblyOverwrittenArgumentOfTailCall(Arg, MFI)
>> ==false ||
>> + (Found==true && "No corresponding Argument was found"));
>> +
>> if (Flags & ISD::ParamFlags::ByVal) {
>> // Copy relative to framepointer.
>> - MemOpChains2.push_back(CreateCopyOfByValArgument(Source,
>> FIN, Chain,
>> + MemOpChains2.push_back(CreateCopyOfByValArgument(Arg,
>> FIN, Chain,
>> Flags,
>> DAG));
>> } else {
>> // Store relative to framepointer.
>> MemOpChains2.push_back(
>> - DAG.getStore(Chain, Source, FIN,
>> + DAG.getStore(Chain, Arg, FIN,
>> PseudoSourceValue::getFixedStack(), FI));
>> }
>> }
>> @@ -1600,8 +1634,16 @@
>> &MemOpChains2[0], MemOpChains2.size());
>>
>> // Store the return address to the appropriate stack slot.
>> - if (FPDiff)
>> - Chain = DAG.getStore(Chain,RetAddrFrIdx, NewRetAddrFrIdx,
>> NULL, 0);
>> + if (FPDiff) {
>> + // Calculate the new stack slot for the return address.
>> + int SlotSize = Is64Bit ? 8 : 4;
>> + int NewReturnAddrFI =
>> + MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-
>> SlotSize);
>> + MVT::ValueType VT = Is64Bit ? MVT::i64 : MVT::i32;
>> + SDOperand NewRetAddrFrIdx = DAG.getFrameIndex
>> (NewReturnAddrFI, VT);
>> + Chain = DAG.getStore(Chain, RetAddrFrIdx, NewRetAddrFrIdx,
>> + PseudoSourceValue::getFixedStack(),
>> NewReturnAddrFI);
>> + }
>> }
>>
>> // If the callee is a GlobalAddress node (quite common, every
>> direct call is)
>>
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/
>> X86ISelLowering.h?rev=47593&r1=47592&r2=47593&view=diff
>>
>> =====================================================================
>> =
>> ========
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Tue Feb 26 03:19:59
>> 2008
>> @@ -482,7 +482,7 @@
>>
>> SDOperand LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
>> const CCValAssign &VA,
>> MachineFrameInfo *MFI,
>> - SDOperand Root, unsigned i);
>> + unsigned CC, SDOperand Root,
>> unsigned i);
>>
>> SDOperand LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
>> const SDOperand &StackPtr,
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list