[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