Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 25 additions & 80 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8360,7 +8360,6 @@ SDValue LoongArchTargetLowering::LowerFormalArguments(
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {

MachineFunction &MF = DAG.getMachineFunction();
auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>();

switch (CallConv) {
default:
Expand Down Expand Up @@ -8425,8 +8424,6 @@ SDValue LoongArchTargetLowering::LowerFormalArguments(
continue;
}
InVals.push_back(ArgValue);
if (Ins[InsIdx].Flags.isByVal())
LoongArchFI->addIncomingByValArgs(ArgValue);
}

if (IsVarArg) {
Expand All @@ -8435,6 +8432,7 @@ SDValue LoongArchTargetLowering::LowerFormalArguments(
const TargetRegisterClass *RC = &LoongArch::GPRRegClass;
MachineFrameInfo &MFI = MF.getFrameInfo();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>();

// Offset of the first variable argument from stack pointer, and size of
// the vararg save area. For now, the varargs save area is either zero or
Expand Down Expand Up @@ -8484,8 +8482,6 @@ SDValue LoongArchTargetLowering::LowerFormalArguments(
LoongArchFI->setVarArgsSaveSize(VarArgsSaveSize);
}

LoongArchFI->setArgumentStackSize(CCInfo.getStackSize());

// All stores are grouped in one node to allow the matching between
// the size of Ins and InVals. This only happens for vararg functions.
if (!OutChains.empty()) {
Expand Down Expand Up @@ -8542,11 +8538,9 @@ bool LoongArchTargetLowering::isEligibleForTailCallOptimization(
auto &Outs = CLI.Outs;
auto &Caller = MF.getFunction();
auto CallerCC = Caller.getCallingConv();
auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>();

// If the stack arguments for this call do not fit into our own save area then
// the call cannot be made tail.
if (CCInfo.getStackSize() > LoongArchFI->getArgumentStackSize())
// Do not tail call opt if the stack is used to pass parameters.
if (CCInfo.getStackSize() != 0)
return false;

// Do not tail call opt if any parameters need to be passed indirectly.
Expand All @@ -8558,19 +8552,13 @@ bool LoongArchTargetLowering::isEligibleForTailCallOptimization(
// semantics.
auto IsCallerStructRet = Caller.hasStructRetAttr();
auto IsCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
if (IsCallerStructRet != IsCalleeStructRet)
if (IsCallerStructRet || IsCalleeStructRet)
return false;

// Do not tail call opt if caller's and callee's byval arguments do not match.
for (unsigned i = 0, j = 0; i < Outs.size(); ++i) {
if (!Outs[i].Flags.isByVal())
continue;
if (j >= LoongArchFI->getIncomingByValArgsSize())
return false;
if (LoongArchFI->getIncomingByValArgs(j).getValueType() != Outs[i].ArgVT)
// Do not tail call opt if either the callee or caller has a byval argument.
for (auto &Arg : Outs)
if (Arg.Flags.isByVal())
return false;
++j;
}

// The callee has to preserve all registers the caller needs to preserve.
const LoongArchRegisterInfo *TRI = Subtarget.getRegisterInfo();
Expand All @@ -8580,14 +8568,6 @@ bool LoongArchTargetLowering::isEligibleForTailCallOptimization(
if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
return false;
}

// If the callee takes no arguments then go on to check the results of the
// call.
const MachineRegisterInfo &MRI = MF.getRegInfo();
const SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals))
return false;

return true;
}

Expand Down Expand Up @@ -8615,7 +8595,6 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
bool &IsTailCall = CLI.IsTailCall;

MachineFunction &MF = DAG.getMachineFunction();
auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>();

// Analyze the operands of the call, assigning locations to each operand.
SmallVector<CCValAssign> ArgLocs;
Expand All @@ -8641,47 +8620,30 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,

// Create local copies for byval args.
SmallVector<SDValue> ByValArgs;
for (unsigned i = 0, j = 0, e = Outs.size(); i != e; ++i) {
for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
ISD::ArgFlagsTy Flags = Outs[i].Flags;
if (!Flags.isByVal())
continue;

SDValue Arg = OutVals[i];
unsigned Size = Flags.getByValSize();
Align Alignment = Flags.getNonZeroByValAlign();

int FI =
MF.getFrameInfo().CreateStackObject(Size, Alignment, /*isSS=*/false);
SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
SDValue SizeNode = DAG.getConstant(Size, DL, GRLenVT);
SDValue Dst;

if (IsTailCall) {
SDValue CallerArg = LoongArchFI->getIncomingByValArgs(j++);
if (isa<GlobalAddressSDNode>(Arg) || isa<ExternalSymbolSDNode>(Arg) ||
isa<FrameIndexSDNode>(Arg))
Dst = CallerArg;
} else {
int FI =
MF.getFrameInfo().CreateStackObject(Size, Alignment, /*isSS=*/false);
Dst = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
}
if (Dst) {
Chain =
DAG.getMemcpy(Chain, DL, Dst, Arg, SizeNode, Alignment,
/*IsVolatile=*/false,
/*AlwaysInline=*/false, /*CI=*/nullptr, std::nullopt,
MachinePointerInfo(), MachinePointerInfo());
ByValArgs.push_back(Dst);
}
Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment,
/*IsVolatile=*/false,
/*AlwaysInline=*/false, /*CI=*/nullptr, std::nullopt,
MachinePointerInfo(), MachinePointerInfo());
ByValArgs.push_back(FIPtr);
}

if (!IsTailCall)
Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);

// During a tail call, stores to the argument area must happen after all of
// the function's incoming arguments have been loaded because they may alias.
// This is done by folding in a TokenFactor from LowerFormalArguments, but
// there's no point in doing so repeatedly so this tracks whether that's
// happened yet.
bool AfterFormalArgLoads = false;

// Copy argument values to their designated locations.
SmallVector<std::pair<Register, SDValue>> RegsToPass;
SmallVector<SDValue> MemOpChains;
Expand Down Expand Up @@ -8776,44 +8738,27 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
}

// Use local copy if it is a byval arg.
if (Flags.isByVal()) {
if (!IsTailCall || (isa<GlobalAddressSDNode>(ArgValue) ||
isa<ExternalSymbolSDNode>(ArgValue) ||
isa<FrameIndexSDNode>(ArgValue)))
ArgValue = ByValArgs[j++];
}
if (Flags.isByVal())
ArgValue = ByValArgs[j++];

if (VA.isRegLoc()) {
// Queue up the argument copies and emit them at the end.
RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
} else {
assert(VA.isMemLoc() && "Argument not register or memory");
SDValue DstAddr;
MachinePointerInfo DstInfo;
int32_t Offset = VA.getLocMemOffset();
assert(!IsTailCall && "Tail call not allowed if stack is used "
"for passing parameters");

// Work out the address of the stack slot.
if (!StackPtr.getNode())
StackPtr = DAG.getCopyFromReg(Chain, DL, LoongArch::R3, PtrVT);

if (IsTailCall) {
unsigned OpSize = divideCeil(VA.getValVT().getSizeInBits(), 8);
int FI = MF.getFrameInfo().CreateFixedObject(OpSize, Offset, true);
DstAddr = DAG.getFrameIndex(FI, PtrVT);
DstInfo = MachinePointerInfo::getFixedStack(MF, FI);
if (!AfterFormalArgLoads) {
Chain = DAG.getStackArgumentTokenFactor(Chain);
AfterFormalArgLoads = true;
}
} else {
SDValue PtrOff = DAG.getIntPtrConstant(Offset, DL);
DstAddr = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff);
DstInfo = MachinePointerInfo::getStack(MF, Offset);
}
SDValue Address =
DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
DAG.getIntPtrConstant(VA.getLocMemOffset(), DL));

// Emit the store.
MemOpChains.push_back(
DAG.getStore(Chain, DL, ArgValue, DstAddr, DstInfo));
DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
}
}

Expand Down
14 changes: 0 additions & 14 deletions llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,10 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
/// Size of stack frame to save callee saved registers
unsigned CalleeSavedStackSize = 0;

/// Amount of bytes on stack consumed by the arguments being passed on
/// the stack
unsigned ArgumentStackSize = 0;

/// FrameIndex of the spill slot when there is no scavenged register in
/// insertIndirectBranch.
int BranchRelaxationSpillFrameIndex = -1;

/// Incoming ByVal arguments
SmallVector<SDValue, 8> IncomingByValArgs;

/// Registers that have been sign extended from i32.
SmallVector<Register, 8> SExt32Registers;

Expand Down Expand Up @@ -70,20 +63,13 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; }
void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; }

unsigned getArgumentStackSize() const { return ArgumentStackSize; }
void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; }

int getBranchRelaxationSpillFrameIndex() {
return BranchRelaxationSpillFrameIndex;
}
void setBranchRelaxationSpillFrameIndex(int Index) {
BranchRelaxationSpillFrameIndex = Index;
}

void addIncomingByValArgs(SDValue Val) { IncomingByValArgs.push_back(Val); }
SDValue getIncomingByValArgs(int Idx) { return IncomingByValArgs[Idx]; }
unsigned getIncomingByValArgsSize() const { return IncomingByValArgs.size(); }

void addSExt32Register(Register Reg) { SExt32Registers.push_back(Reg); }

bool isSExt32Register(Register Reg) const {
Expand Down
Loading
Loading