[llvm] r224745 - Make musttail more robust for vector types on x86
Aaron Ballman
aaron at aaronballman.com
Sat Dec 27 11:02:50 PST 2014
On Tue, Dec 23, 2014 at 9:40 AM, Aaron Ballman <aaron at aaronballman.com> wrote:
> On Mon, Dec 22, 2014 at 6:58 PM, Reid Kleckner <reid at kleckner.net> wrote:
>> Author: rnk
>> Date: Mon Dec 22 17:58:37 2014
>> New Revision: 224745
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=224745&view=rev
>> Log:
>> Make musttail more robust for vector types on x86
>>
>> Previously I tried to plug musttail into the existing vararg lowering
>> code. That turned out to be a mistake, because non-vararg calls use
>> significantly different register lowering, even on x86. For example, AVX
>> vectors are usually passed in registers to normal functions and memory
>> to vararg functions. Now musttail uses a completely separate lowering.
>>
>> Hopefully this can be used as the basis for non-x86 perfect forwarding.
>>
>> Reviewers: majnemer
>>
>> Differential Revision: http://reviews.llvm.org/D6156
>>
>> Added:
>> llvm/trunk/test/CodeGen/X86/musttail-fastcall.ll
>> Modified:
>> llvm/trunk/include/llvm/CodeGen/CallingConvLower.h
>> llvm/trunk/lib/CodeGen/CallingConvLower.cpp
>> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>> llvm/trunk/lib/Target/X86/X86MachineFunctionInfo.h
>> llvm/trunk/test/CodeGen/X86/musttail-varargs.ll
>>
>> Modified: llvm/trunk/include/llvm/CodeGen/CallingConvLower.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CallingConvLower.h?rev=224745&r1=224744&r2=224745&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/CodeGen/CallingConvLower.h (original)
>> +++ llvm/trunk/include/llvm/CodeGen/CallingConvLower.h Mon Dec 22 17:58:37 2014
>> @@ -158,6 +158,16 @@ public:
>> }
>> };
>>
>> +/// Describes a register that needs to be forwarded from the prologue to a
>> +/// musttail call.
>> +struct ForwardedRegister {
>> + ForwardedRegister(unsigned VReg, MCPhysReg PReg, MVT VT)
>> + : VReg(VReg), PReg(PReg), VT(VT) {}
>> + unsigned VReg;
>> + MCPhysReg PReg;
>> + MVT VT;
>> +};
>> +
>> /// CCAssignFn - This function assigns a location for Val, updating State to
>> /// reflect the change. It returns 'true' if it failed to handle Val.
>> typedef bool CCAssignFn(unsigned ValNo, MVT ValVT,
>> @@ -470,6 +480,19 @@ public:
>> return PendingLocs;
>> }
>>
>> + /// Compute the remaining unused register parameters that would be used for
>> + /// the given value type. This is useful when varargs are passed in the
>> + /// registers that normal prototyped parameters would be passed in, or for
>> + /// implementing perfect forwarding.
>> + void getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs, MVT VT,
>> + CCAssignFn Fn);
>> +
>> + /// Compute the set of registers that need to be preserved and forwarded to
>> + /// any musttail calls.
>> + void analyzeMustTailForwardedRegisters(
>> + SmallVectorImpl<ForwardedRegister> &Forwards, ArrayRef<MVT> RegParmTypes,
>> + CCAssignFn Fn);
>> +
>> private:
>> /// MarkAllocated - Mark a register and all of its aliases as allocated.
>> void MarkAllocated(unsigned Reg);
>>
>> Modified: llvm/trunk/lib/CodeGen/CallingConvLower.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CallingConvLower.cpp?rev=224745&r1=224744&r2=224745&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/CallingConvLower.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/CallingConvLower.cpp Mon Dec 22 17:58:37 2014
>> @@ -14,9 +14,11 @@
>>
>> #include "llvm/CodeGen/CallingConvLower.h"
>> #include "llvm/CodeGen/MachineFrameInfo.h"
>> +#include "llvm/CodeGen/MachineRegisterInfo.h"
>> #include "llvm/IR/DataLayout.h"
>> #include "llvm/Support/Debug.h"
>> #include "llvm/Support/ErrorHandling.h"
>> +#include "llvm/Support/SaveAndRestore.h"
>> #include "llvm/Support/raw_ostream.h"
>> #include "llvm/Target/TargetLowering.h"
>> #include "llvm/Target/TargetRegisterInfo.h"
>> @@ -178,3 +180,57 @@ void CCState::AnalyzeCallResult(MVT VT,
>> llvm_unreachable(nullptr);
>> }
>> }
>> +
>> +void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs,
>> + MVT VT, CCAssignFn Fn) {
>> + unsigned SavedStackOffset = StackOffset;
>> + unsigned NumLocs = Locs.size();
>> +
>> + // Allocate something of this value type repeatedly with just the inreg flag
>> + // set until we get assigned a location in memory.
>> + ISD::ArgFlagsTy Flags;
>> + Flags.setInReg();
>> + bool HaveRegParm = true;
>> + while (HaveRegParm) {
>> + if (Fn(0, VT, VT, CCValAssign::Full, Flags, *this)) {
>> +#ifndef NDEBUG
>> + dbgs() << "Call has unhandled type " << EVT(VT).getEVTString()
>> + << " while computing remaining regparms\n";
>> +#endif
>> + llvm_unreachable(nullptr);
>> + }
>> + HaveRegParm = Locs.back().isRegLoc();
>> + }
>> +
>> + // Copy all the registers from the value locations we added.
>> + assert(NumLocs < Locs.size() && "CC assignment failed to add location");
>> + for (unsigned I = NumLocs, E = Locs.size(); I != E; ++I)
>> + if (Locs[I].isRegLoc())
>> + Regs.push_back(MCPhysReg(Locs[I].getLocReg()));
>> +
>> + // Clear the assigned values and stack memory. We leave the registers marked
>> + // as allocated so that future queries don't return the same registers, i.e.
>> + // when i64 and f64 are both passed in GPRs.
>> + StackOffset = SavedStackOffset;
>> + Locs.resize(NumLocs);
>> +}
>> +
>> +void CCState::analyzeMustTailForwardedRegisters(
>> + SmallVectorImpl<ForwardedRegister> &Forwards, ArrayRef<MVT> RegParmTypes,
>> + CCAssignFn Fn) {
>> + // Oftentimes calling conventions will not user register parameters for
>> + // variadic functions, so we need to assume we're not variadic so that we get
>> + // all the registers that might be used in a non-variadic call.
>> + SaveAndRestore<bool> SavedVarArg(IsVarArg, false);
>> +
>> + for (MVT RegVT : RegParmTypes) {
>> + SmallVector<MCPhysReg, 8> RemainingRegs;
>> + getRemainingRegParmsForType(RemainingRegs, RegVT, Fn);
>> + const TargetLowering *TL = MF.getSubtarget().getTargetLowering();
>> + const TargetRegisterClass *RC = TL->getRegClassFor(RegVT);
>> + for (MCPhysReg PReg : RemainingRegs) {
>> + unsigned VReg = MF.addLiveIn(PReg, RC);
>> + Forwards.push_back(ForwardedRegister(VReg, PReg, RegVT));
>> + }
>> + }
>> +}
>>
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=224745&r1=224744&r2=224745&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec 22 17:58:37 2014
>> @@ -2549,11 +2549,19 @@ X86TargetLowering::LowerFormalArguments(
>> MFI->CreateFixedObject(1, StackSize, true));
>> }
>>
>> + // Figure out if XMM registers are in use.
>> + bool HaveXMMArgs = Is64Bit && !IsWin64;
>
> I am now getting: warning: variable ‘HaveXMMArgs’ set but not used
> [-Wunused-but-set-variable]
>
> Was there a purpose for HaveXMMArgs, or can this simply be removed?
I have removed it in r224888 -- if it was meant to serve a purpose, it
will be trivial to revive.
~Aaron
More information about the llvm-commits
mailing list