void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL,
const FuncInfoTy &FuncInfo) const;
+ /// Break \p OrigArgInfo into one or more pieces the calling convention can
+ /// process, returned in \p SplitArgs. For example, this should break structs
+ /// down into individual fields.
+ void splitToValueTypes(const ArgInfo &OrigArgInfo,
+ SmallVectorImpl<ArgInfo> &SplitArgs,
+ const DataLayout &DL, CallingConv::ID CallConv) const;
+
/// Generate instructions for packing \p SrcRegs into one big register
/// corresponding to the aggregate type \p PackedTy.
///
const DataLayout &DL,
const CallBase &FuncInfo) const;
+void CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
+ SmallVectorImpl<ArgInfo> &SplitArgs,
+ const DataLayout &DL,
+ CallingConv::ID CallConv) const {
+ LLVMContext &Ctx = OrigArg.Ty->getContext();
+
+ SmallVector<EVT, 4> SplitVTs;
+ SmallVector<uint64_t, 4> Offsets;
+ ComputeValueVTs(*TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
+
+ if (SplitVTs.size() == 0)
+ return;
+
+ if (SplitVTs.size() == 1) {
+ // No splitting to do, but we want to replace the original type (e.g. [1 x
+ // double] -> double).
+ SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
+ OrigArg.Flags[0], OrigArg.IsFixed);
+ return;
+ }
+
+ // Create one ArgInfo for each virtual register in the original ArgInfo.
+ assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch");
+
+ bool NeedsRegBlock = TLI->functionArgumentNeedsConsecutiveRegisters(
+ OrigArg.Ty, CallConv, false);
+ for (unsigned i = 0, e = SplitVTs.size(); i < e; ++i) {
+ Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx);
+ SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags[0],
+ OrigArg.IsFixed);
+ if (NeedsRegBlock)
+ SplitArgs.back().Flags[0].setInConsecutiveRegs();
+ }
+
+ SplitArgs.back().Flags[0].setInConsecutiveRegsLast();
+}
+
Register CallLowering::packRegs(ArrayRef<Register> SrcRegs, Type *PackedTy,
MachineIRBuilder &MIRBuilder) const {
assert(SrcRegs.size() > 1 && "Nothing to pack");
return CallConv == CallingConv::Fast && TailCallOpt;
}
-void AArch64CallLowering::splitToValueTypes(
- const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs,
- const DataLayout &DL, MachineRegisterInfo &MRI, CallingConv::ID CallConv) const {
- const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
- LLVMContext &Ctx = OrigArg.Ty->getContext();
-
- SmallVector<EVT, 4> SplitVTs;
- SmallVector<uint64_t, 4> Offsets;
- ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
-
- if (SplitVTs.size() == 0)
- return;
-
- if (SplitVTs.size() == 1) {
- // No splitting to do, but we want to replace the original type (e.g. [1 x
- // double] -> double).
- SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
- OrigArg.Flags[0], OrigArg.IsFixed);
- return;
- }
-
- // Create one ArgInfo for each virtual register in the original ArgInfo.
- assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch");
-
- bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters(
- OrigArg.Ty, CallConv, false);
- for (unsigned i = 0, e = SplitVTs.size(); i < e; ++i) {
- Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx);
- SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags[0],
- OrigArg.IsFixed);
- if (NeedsRegBlock)
- SplitArgs.back().Flags[0].setInConsecutiveRegs();
- }
-
- SplitArgs.back().Flags[0].setInConsecutiveRegsLast();
-}
-
bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
const Value *Val,
ArrayRef<Register> VRegs,
// Reset the arg flags after modifying CurVReg.
setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
}
- splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, CC);
+ splitToValueTypes(CurArgInfo, SplitArgs, DL, CC);
}
OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFn, AssignFn);
ArgInfo OrigArg{VRegs[i], Arg.getType()};
setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, F);
- splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv());
+ splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
++i;
}
SmallVector<ArgInfo, 8> OutArgs;
for (auto &OrigArg : Info.OrigArgs) {
- splitToValueTypes(OrigArg, OutArgs, DL, MRI, Info.CallConv);
+ splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv);
// AAPCS requires that we zero-extend i1 to 8 bits by the caller.
if (OrigArg.Ty->isIntegerTy(1))
OutArgs.back().Flags[0].setZExt();
SmallVector<ArgInfo, 8> InArgs;
if (!Info.OrigRet.Ty->isVoidTy())
- splitToValueTypes(Info.OrigRet, InArgs, DL, MRI, Info.CallConv);
+ splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);
// If we can lower as a tail call, do that instead.
bool CanTailCallOpt =
using MemHandler =
std::function<void(MachineIRBuilder &, int, CCValAssign &)>;
- void splitToValueTypes(const ArgInfo &OrigArgInfo,
- SmallVectorImpl<ArgInfo> &SplitArgs,
- const DataLayout &DL, MachineRegisterInfo &MRI,
- CallingConv::ID CallConv) const;
-
bool lowerTailCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info,
SmallVectorImpl<ArgInfo> &OutArgs) const;
}
}
-// FIXME: This should move to generic code.
-void AMDGPUCallLowering::splitToValueTypes(MachineIRBuilder &B,
- const ArgInfo &OrigArg,
- SmallVectorImpl<ArgInfo> &SplitArgs,
- const DataLayout &DL,
- CallingConv::ID CallConv) const {
- const SITargetLowering &TLI = *getTLI<SITargetLowering>();
- LLVMContext &Ctx = OrigArg.Ty->getContext();
-
- SmallVector<EVT, 4> SplitVTs;
- ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs);
-
- assert(OrigArg.Regs.size() == SplitVTs.size());
-
- if (SplitVTs.size() == 0)
- return;
-
- if (SplitVTs.size() == 1) {
- // No splitting to do, but we want to replace the original type (e.g. [1 x
- // double] -> double).
- SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
- OrigArg.Flags[0], OrigArg.IsFixed);
- return;
- }
-
- // Create one ArgInfo for each virtual register in the original ArgInfo.
- assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch");
-
- bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters(
- OrigArg.Ty, CallConv, false);
- for (unsigned i = 0, e = SplitVTs.size(); i < e; ++i) {
- Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx);
- SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags[0],
- OrigArg.IsFixed);
- if (NeedsRegBlock)
- SplitArgs.back().Flags[0].setInConsecutiveRegs();
- }
-
- SplitArgs.back().Flags[0].setInConsecutiveRegsLast();
-}
-
void AMDGPUCallLowering::processSplitArgs(
MachineIRBuilder &B, const ArgInfo &OrigArg,
const SmallVectorImpl<ArgInfo> &SplitArg,
setArgFlags(RetInfo, AttributeList::ReturnIndex, DL, F);
}
- splitToValueTypes(B, RetInfo, PreSplitRetInfos, DL, CC);
+ splitToValueTypes(RetInfo, PreSplitRetInfos, DL, CC);
// FIXME: This splitting should mostly be done by handleAssignments
processSplitArgs(B, RetInfo,
const unsigned OrigArgIdx = Idx + AttributeList::FirstArgIndex;
setArgFlags(OrigArg, OrigArgIdx, DL, F);
- splitToValueTypes(B, OrigArg, SplitArgs, DL, CC);
+ splitToValueTypes(OrigArg, SplitArgs, DL, CC);
++Idx;
}
SmallVector<ArgInfo, 8> SplitArg;
for (auto &OrigArg : Info.OrigArgs) {
- splitToValueTypes(MIRBuilder, OrigArg, SplitArg, DL, Info.CallConv);
+ splitToValueTypes(OrigArg, SplitArg, DL, Info.CallConv);
processSplitArgs(
MIRBuilder, OrigArg, SplitArg, OutArgs, DL, Info.CallConv, true,
insertSRetLoads(MIRBuilder, Info.OrigRet.Ty, Info.OrigRet.Regs,
Info.DemoteRegister, Info.DemoteStackIndex);
} else if (!Info.OrigRet.Ty->isVoidTy()) {
- splitToValueTypes(MIRBuilder, Info.OrigRet, InArgs, DL, Info.CallConv);
+ splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv);
}
// Make sure the raw argument copies are inserted before the marshalling to
/// A function of this type is used to perform value split action.
using SplitArgTy = std::function<void(ArrayRef<Register>, Register, LLT, LLT, int)>;
- void splitToValueTypes(MachineIRBuilder &B, const ArgInfo &OrigArgInfo,
- SmallVectorImpl<ArgInfo> &SplitArgs,
- const DataLayout &DL, CallingConv::ID CallConv) const;
-
void processSplitArgs(MachineIRBuilder &B, const ArgInfo &OrigArgInfo,
const SmallVectorImpl<ArgInfo> &SplitArg,
SmallVectorImpl<ArgInfo> &SplitArgs,
} // end anonymous namespace
-void ARMCallLowering::splitToValueTypes(const ArgInfo &OrigArg,
- SmallVectorImpl<ArgInfo> &SplitArgs,
- MachineFunction &MF) const {
- const ARMTargetLowering &TLI = *getTLI<ARMTargetLowering>();
- LLVMContext &Ctx = OrigArg.Ty->getContext();
- const DataLayout &DL = MF.getDataLayout();
- const Function &F = MF.getFunction();
-
- SmallVector<EVT, 4> SplitVTs;
- ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, nullptr, nullptr, 0);
- assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch");
-
- if (SplitVTs.size() == 1) {
- // Even if there is no splitting to do, we still want to replace the
- // original type (e.g. pointer type -> integer).
- auto Flags = OrigArg.Flags[0];
- Flags.setOrigAlign(DL.getABITypeAlign(OrigArg.Ty));
- SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
- Flags, OrigArg.IsFixed);
- return;
- }
-
- // Create one ArgInfo for each virtual register.
- for (unsigned i = 0, e = SplitVTs.size(); i != e; ++i) {
- EVT SplitVT = SplitVTs[i];
- Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
- auto Flags = OrigArg.Flags[0];
-
- Flags.setOrigAlign(DL.getABITypeAlign(SplitTy));
-
- bool NeedsConsecutiveRegisters =
- TLI.functionArgumentNeedsConsecutiveRegisters(
- SplitTy, F.getCallingConv(), F.isVarArg());
- if (NeedsConsecutiveRegisters) {
- Flags.setInConsecutiveRegs();
- if (i == e - 1)
- Flags.setInConsecutiveRegsLast();
- }
-
- // FIXME: We also want to split SplitTy further.
- Register PartReg = OrigArg.Regs[i];
- SplitArgs.emplace_back(PartReg, SplitTy, Flags, OrigArg.IsFixed);
- }
-}
-
/// Lower the return value for the already existing \p Ret. This assumes that
/// \p MIRBuilder's insertion point is correct.
bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
auto &MF = MIRBuilder.getMF();
const auto &F = MF.getFunction();
- auto DL = MF.getDataLayout();
+ const auto &DL = MF.getDataLayout();
auto &TLI = *getTLI<ARMTargetLowering>();
if (!isSupportedType(DL, TLI, Val->getType()))
return false;
setArgFlags(OrigRetInfo, AttributeList::ReturnIndex, DL, F);
SmallVector<ArgInfo, 4> SplitRetInfos;
- splitToValueTypes(OrigRetInfo, SplitRetInfos, MF);
+ splitToValueTypes(OrigRetInfo, SplitRetInfos, DL, F.getCallingConv());
CCAssignFn *AssignFn =
TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
auto &MF = MIRBuilder.getMF();
auto &MBB = MIRBuilder.getMBB();
- auto DL = MF.getDataLayout();
+ const auto &DL = MF.getDataLayout();
for (auto &Arg : F.args()) {
if (!isSupportedType(DL, TLI, Arg.getType()))
ArgInfo OrigArgInfo(VRegs[Idx], Arg.getType());
setArgFlags(OrigArgInfo, Idx + AttributeList::FirstArgIndex, DL, F);
- splitToValueTypes(OrigArgInfo, SplitArgInfos, MF);
+ splitToValueTypes(OrigArgInfo, SplitArgInfos, DL, F.getCallingConv());
Idx++;
}
if (Arg.Flags[0].isByVal())
return false;
- splitToValueTypes(Arg, ArgInfos, MF);
+ splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv);
}
auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, Info.IsVarArg);
return false;
ArgInfos.clear();
- splitToValueTypes(Info.OrigRet, ArgInfos, MF);
+ splitToValueTypes(Info.OrigRet, ArgInfos, DL, Info.CallConv);
auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, Info.IsVarArg);
CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler, Info.CallConv,
bool lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val,
ArrayRef<Register> VRegs,
MachineInstrBuilder &Ret) const;
-
- /// Split an argument into one or more arguments that the CC lowering can cope
- /// with.
- void splitToValueTypes(const ArgInfo &OrigArg,
- SmallVectorImpl<ArgInfo> &SplitArgs,
- MachineFunction &MF) const;
};
} // end namespace llvm
}
}
+// FIXME: This should be removed and the generic version used
void MipsCallLowering::splitToValueTypes(
const DataLayout &DL, const ArgInfo &OrigArg, unsigned OriginalIndex,
SmallVectorImpl<ArgInfo> &SplitArgs,
X86CallLowering::X86CallLowering(const X86TargetLowering &TLI)
: CallLowering(&TLI) {}
+// FIXME: This should be removed and the generic version used
bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
SmallVectorImpl<ArgInfo> &SplitArgs,
const DataLayout &DL,