Skip to content

Commit 498ef36

Browse files
authored
[CodeGen] Make OrigTy in CC lowering the non-aggregate type (#153414)
#152709 exposed the original IR argument type to the CC lowering logic. However, in SDAG, this used the raw type, prior to aggregate splitting. This PR changes it to use the non-aggregate type instead. (This matches what happened in the GlobalISel case already.) I've also added some more detailed documentation on the InputArg/OutputArg fields, to explain how they differ. In most cases ArgVT is going to be the EVT of OrigTy, so they encode very similar information (OrigTy just preserves some additional information lost in EVTs, like pointer types). One case where they do differ is in post-legalization lowering of libcalls, where ArgVT is going to be a legalized type, while OrigTy is going to be the original non-legalized type.
1 parent 0f77887 commit 498ef36

File tree

5 files changed

+86
-56
lines changed

5 files changed

+86
-56
lines changed

llvm/include/llvm/CodeGen/Analysis.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ inline unsigned ComputeLinearIndex(Type *Ty,
5555
return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex);
5656
}
5757

58+
/// Given an LLVM IR type, compute non-aggregate subtypes. Optionally also
59+
/// compute their offsets.
60+
void ComputeValueTypes(const DataLayout &DL, Type *Ty,
61+
SmallVectorImpl<Type *> &Types,
62+
SmallVectorImpl<TypeSize> *Offsets = nullptr,
63+
TypeSize StartingOffset = TypeSize::getZero());
64+
5865
/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
5966
/// EVTs that represent all the individual underlying
6067
/// non-aggregate types that comprise it.

llvm/include/llvm/CodeGen/TargetCallingConv.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,14 @@ namespace ISD {
203203
///
204204
struct InputArg {
205205
ArgFlagsTy Flags;
206+
/// Legalized type of this argument part.
206207
MVT VT = MVT::Other;
208+
/// Usually the non-legalized type of the argument, which is the EVT
209+
/// corresponding to the OrigTy IR type. However, for post-legalization
210+
/// libcalls, this will be a legalized type.
207211
EVT ArgVT;
212+
/// Original IR type of the argument. For aggregates, this is the type of
213+
/// an individual aggregate element, not the whole aggregate.
208214
Type *OrigTy;
209215
bool Used;
210216

@@ -239,8 +245,13 @@ namespace ISD {
239245
///
240246
struct OutputArg {
241247
ArgFlagsTy Flags;
248+
// Legalized type of this argument part.
242249
MVT VT;
250+
/// Non-legalized type of the argument. This is the EVT corresponding to
251+
/// the OrigTy IR type.
243252
EVT ArgVT;
253+
/// Original IR type of the argument. For aggregates, this is the type of
254+
/// an individual aggregate element, not the whole aggregate.
244255
Type *OrigTy;
245256

246257
/// Index original Function's argument.

llvm/lib/CodeGen/Analysis.cpp

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,10 @@ unsigned llvm::ComputeLinearIndex(Type *Ty,
6969
return CurIndex + 1;
7070
}
7171

72-
/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
73-
/// EVTs that represent all the individual underlying
74-
/// non-aggregate types that comprise it.
75-
///
76-
/// If Offsets is non-null, it points to a vector to be filled in
77-
/// with the in-memory offsets of each of the individual values.
78-
///
79-
void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
80-
Type *Ty, SmallVectorImpl<EVT> &ValueVTs,
81-
SmallVectorImpl<EVT> *MemVTs,
82-
SmallVectorImpl<TypeSize> *Offsets,
83-
TypeSize StartingOffset) {
72+
void llvm::ComputeValueTypes(const DataLayout &DL, Type *Ty,
73+
SmallVectorImpl<Type *> &Types,
74+
SmallVectorImpl<TypeSize> *Offsets,
75+
TypeSize StartingOffset) {
8476
assert((Ty->isScalableTy() == StartingOffset.isScalable() ||
8577
StartingOffset.isZero()) &&
8678
"Offset/TypeSize mismatch!");
@@ -90,15 +82,13 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
9082
// us to support structs with scalable vectors for operations that don't
9183
// need offsets.
9284
const StructLayout *SL = Offsets ? DL.getStructLayout(STy) : nullptr;
93-
for (StructType::element_iterator EB = STy->element_begin(),
94-
EI = EB,
85+
for (StructType::element_iterator EB = STy->element_begin(), EI = EB,
9586
EE = STy->element_end();
9687
EI != EE; ++EI) {
9788
// Don't compute the element offset if we didn't get a StructLayout above.
9889
TypeSize EltOffset =
9990
SL ? SL->getElementOffset(EI - EB) : TypeSize::getZero();
100-
ComputeValueVTs(TLI, DL, *EI, ValueVTs, MemVTs, Offsets,
101-
StartingOffset + EltOffset);
91+
ComputeValueTypes(DL, *EI, Types, Offsets, StartingOffset + EltOffset);
10292
}
10393
return;
10494
}
@@ -107,21 +97,39 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
10797
Type *EltTy = ATy->getElementType();
10898
TypeSize EltSize = DL.getTypeAllocSize(EltTy);
10999
for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
110-
ComputeValueVTs(TLI, DL, EltTy, ValueVTs, MemVTs, Offsets,
111-
StartingOffset + i * EltSize);
100+
ComputeValueTypes(DL, EltTy, Types, Offsets,
101+
StartingOffset + i * EltSize);
112102
return;
113103
}
114104
// Interpret void as zero return values.
115105
if (Ty->isVoidTy())
116106
return;
117-
// Base case: we can get an EVT for this LLVM IR type.
118-
ValueVTs.push_back(TLI.getValueType(DL, Ty));
119-
if (MemVTs)
120-
MemVTs->push_back(TLI.getMemValueType(DL, Ty));
107+
Types.push_back(Ty);
121108
if (Offsets)
122109
Offsets->push_back(StartingOffset);
123110
}
124111

112+
/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
113+
/// EVTs that represent all the individual underlying
114+
/// non-aggregate types that comprise it.
115+
///
116+
/// If Offsets is non-null, it points to a vector to be filled in
117+
/// with the in-memory offsets of each of the individual values.
118+
///
119+
void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
120+
Type *Ty, SmallVectorImpl<EVT> &ValueVTs,
121+
SmallVectorImpl<EVT> *MemVTs,
122+
SmallVectorImpl<TypeSize> *Offsets,
123+
TypeSize StartingOffset) {
124+
SmallVector<Type *> Types;
125+
ComputeValueTypes(DL, Ty, Types, Offsets, StartingOffset);
126+
for (Type *Ty : Types) {
127+
ValueVTs.push_back(TLI.getValueType(DL, Ty));
128+
if (MemVTs)
129+
MemVTs->push_back(TLI.getMemValueType(DL, Ty));
130+
}
131+
}
132+
125133
void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL,
126134
Type *Ty, SmallVectorImpl<EVT> &ValueVTs,
127135
SmallVectorImpl<EVT> *MemVTs,

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,9 +2211,9 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
22112211
Chain = DAG.getNode(ISD::TokenFactor, getCurSDLoc(),
22122212
MVT::Other, Chains);
22132213
} else if (I.getNumOperands() != 0) {
2214-
SmallVector<EVT, 4> ValueVTs;
2215-
ComputeValueVTs(TLI, DL, I.getOperand(0)->getType(), ValueVTs);
2216-
unsigned NumValues = ValueVTs.size();
2214+
SmallVector<Type *, 4> Types;
2215+
ComputeValueTypes(DL, I.getOperand(0)->getType(), Types);
2216+
unsigned NumValues = Types.size();
22172217
if (NumValues) {
22182218
SDValue RetOp = getValue(I.getOperand(0));
22192219

@@ -2233,7 +2233,7 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
22332233
bool RetInReg = F->getAttributes().hasRetAttr(Attribute::InReg);
22342234

22352235
for (unsigned j = 0; j != NumValues; ++j) {
2236-
EVT VT = ValueVTs[j];
2236+
EVT VT = TLI.getValueType(DL, Types[j]);
22372237

22382238
if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger())
22392239
VT = TLI.getTypeForExtReturn(Context, VT, ExtendKind);
@@ -2275,7 +2275,7 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
22752275
for (unsigned i = 0; i < NumParts; ++i) {
22762276
Outs.push_back(ISD::OutputArg(Flags,
22772277
Parts[i].getValueType().getSimpleVT(),
2278-
VT, I.getOperand(0)->getType(), 0, 0));
2278+
VT, Types[j], 0, 0));
22792279
OutVals.push_back(Parts[i]);
22802280
}
22812281
}
@@ -10983,15 +10983,21 @@ std::pair<SDValue, SDValue>
1098310983
TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
1098410984
// Handle the incoming return values from the call.
1098510985
CLI.Ins.clear();
10986-
SmallVector<EVT, 4> RetTys;
10986+
SmallVector<Type *, 4> RetOrigTys;
1098710987
SmallVector<TypeSize, 4> Offsets;
1098810988
auto &DL = CLI.DAG.getDataLayout();
10989-
ComputeValueVTs(*this, DL, CLI.RetTy, RetTys, &Offsets);
10989+
ComputeValueTypes(DL, CLI.RetTy, RetOrigTys, &Offsets);
10990+
10991+
SmallVector<EVT, 4> RetTys;
10992+
for (Type *Ty : RetOrigTys)
10993+
RetTys.push_back(getValueType(DL, Ty));
1099010994

1099110995
if (CLI.IsPostTypeLegalization) {
1099210996
// If we are lowering a libcall after legalization, split the return type.
10997+
SmallVector<Type *, 4> OldRetOrigTys;
1099310998
SmallVector<EVT, 4> OldRetTys;
1099410999
SmallVector<TypeSize, 4> OldOffsets;
11000+
RetOrigTys.swap(OldRetOrigTys);
1099511001
RetTys.swap(OldRetTys);
1099611002
Offsets.swap(OldOffsets);
1099711003

@@ -11001,6 +11007,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
1100111007
MVT RegisterVT = getRegisterType(CLI.RetTy->getContext(), RetVT);
1100211008
unsigned NumRegs = getNumRegisters(CLI.RetTy->getContext(), RetVT);
1100311009
unsigned RegisterVTByteSZ = RegisterVT.getSizeInBits() / 8;
11010+
RetOrigTys.append(NumRegs, OldRetOrigTys[i]);
1100411011
RetTys.append(NumRegs, RegisterVT);
1100511012
for (unsigned j = 0; j != NumRegs; ++j)
1100611013
Offsets.push_back(TypeSize::getFixed(Offset + j * RegisterVTByteSZ));
@@ -11069,7 +11076,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
1106911076
unsigned NumRegs = getNumRegistersForCallingConv(CLI.RetTy->getContext(),
1107011077
CLI.CallConv, VT);
1107111078
for (unsigned i = 0; i != NumRegs; ++i) {
11072-
ISD::InputArg Ret(Flags, RegisterVT, VT, CLI.RetTy,
11079+
ISD::InputArg Ret(Flags, RegisterVT, VT, RetOrigTys[I],
1107311080
CLI.IsReturnValueUsed, ISD::InputArg::NoArgIndex, 0);
1107411081
if (CLI.RetTy->isPointerTy()) {
1107511082
Ret.Flags.setPointer();
@@ -11106,18 +11113,18 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
1110611113
CLI.Outs.clear();
1110711114
CLI.OutVals.clear();
1110811115
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
11109-
SmallVector<EVT, 4> ValueVTs;
11110-
ComputeValueVTs(*this, DL, Args[i].Ty, ValueVTs);
11116+
SmallVector<Type *, 4> ArgTys;
11117+
ComputeValueTypes(DL, Args[i].Ty, ArgTys);
1111111118
// FIXME: Split arguments if CLI.IsPostTypeLegalization
1111211119
Type *FinalType = Args[i].Ty;
1111311120
if (Args[i].IsByVal)
1111411121
FinalType = Args[i].IndirectType;
1111511122
bool NeedsRegBlock = functionArgumentNeedsConsecutiveRegisters(
1111611123
FinalType, CLI.CallConv, CLI.IsVarArg, DL);
11117-
for (unsigned Value = 0, NumValues = ValueVTs.size(); Value != NumValues;
11124+
for (unsigned Value = 0, NumValues = ArgTys.size(); Value != NumValues;
1111811125
++Value) {
11119-
EVT VT = ValueVTs[Value];
11120-
Type *ArgTy = VT.getTypeForEVT(CLI.RetTy->getContext());
11126+
Type *ArgTy = ArgTys[Value];
11127+
EVT VT = getValueType(DL, ArgTy);
1112111128
SDValue Op = SDValue(Args[i].Node.getNode(),
1112211129
Args[i].Node.getResNo() + Value);
1112311130
ISD::ArgFlagsTy Flags;
@@ -11130,10 +11137,9 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
1113011137

1113111138
if (i >= CLI.NumFixedArgs)
1113211139
Flags.setVarArg();
11133-
if (Args[i].Ty->isPointerTy()) {
11140+
if (ArgTy->isPointerTy()) {
1113411141
Flags.setPointer();
11135-
Flags.setPointerAddrSpace(
11136-
cast<PointerType>(Args[i].Ty)->getAddressSpace());
11142+
Flags.setPointerAddrSpace(cast<PointerType>(ArgTy)->getAddressSpace());
1113711143
}
1113811144
if (Args[i].IsZExt)
1113911145
Flags.setZExt();
@@ -11252,7 +11258,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
1125211258
// For scalable vectors the scalable part is currently handled
1125311259
// by individual targets, so we just use the known minimum size here.
1125411260
ISD::OutputArg MyFlags(
11255-
Flags, Parts[j].getValueType().getSimpleVT(), VT, Args[i].Ty, i,
11261+
Flags, Parts[j].getValueType().getSimpleVT(), VT, ArgTy, i,
1125611262
j * Parts[j].getValueType().getStoreSize().getKnownMinValue());
1125711263
if (NumParts > 1 && j == 0)
1125811264
MyFlags.Flags.setSplit();
@@ -11645,26 +11651,24 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
1164511651
// Set up the incoming argument description vector.
1164611652
for (const Argument &Arg : F.args()) {
1164711653
unsigned ArgNo = Arg.getArgNo();
11648-
SmallVector<EVT, 4> ValueVTs;
11649-
ComputeValueVTs(*TLI, DAG.getDataLayout(), Arg.getType(), ValueVTs);
11654+
SmallVector<Type *, 4> Types;
11655+
ComputeValueTypes(DAG.getDataLayout(), Arg.getType(), Types);
1165011656
bool isArgValueUsed = !Arg.use_empty();
1165111657
unsigned PartBase = 0;
1165211658
Type *FinalType = Arg.getType();
1165311659
if (Arg.hasAttribute(Attribute::ByVal))
1165411660
FinalType = Arg.getParamByValType();
1165511661
bool NeedsRegBlock = TLI->functionArgumentNeedsConsecutiveRegisters(
1165611662
FinalType, F.getCallingConv(), F.isVarArg(), DL);
11657-
for (unsigned Value = 0, NumValues = ValueVTs.size();
11658-
Value != NumValues; ++Value) {
11659-
EVT VT = ValueVTs[Value];
11660-
Type *ArgTy = VT.getTypeForEVT(*DAG.getContext());
11663+
for (unsigned Value = 0, NumValues = Types.size(); Value != NumValues;
11664+
++Value) {
11665+
Type *ArgTy = Types[Value];
11666+
EVT VT = TLI->getValueType(DL, ArgTy);
1166111667
ISD::ArgFlagsTy Flags;
1166211668

11663-
11664-
if (Arg.getType()->isPointerTy()) {
11669+
if (ArgTy->isPointerTy()) {
1166511670
Flags.setPointer();
11666-
Flags.setPointerAddrSpace(
11667-
cast<PointerType>(Arg.getType())->getAddressSpace());
11671+
Flags.setPointerAddrSpace(cast<PointerType>(ArgTy)->getAddressSpace());
1166811672
}
1166911673
if (Arg.hasAttribute(Attribute::ZExt))
1167011674
Flags.setZExt();
@@ -11768,7 +11772,7 @@ void SelectionDAGISel::LowerArguments(const Function &F) {
1176811772
// are responsible for handling scalable vector arguments and
1176911773
// return values.
1177011774
ISD::InputArg MyFlags(
11771-
Flags, RegisterVT, VT, Arg.getType(), isArgValueUsed, ArgNo,
11775+
Flags, RegisterVT, VT, ArgTy, isArgValueUsed, ArgNo,
1177211776
PartBase + i * RegisterVT.getStoreSize().getKnownMinValue());
1177311777
if (NumRegs > 1 && i == 0)
1177411778
MyFlags.Flags.setSplit();

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,13 +1738,13 @@ void llvm::GetReturnInfo(CallingConv::ID CC, Type *ReturnType,
17381738
AttributeList attr,
17391739
SmallVectorImpl<ISD::OutputArg> &Outs,
17401740
const TargetLowering &TLI, const DataLayout &DL) {
1741-
SmallVector<EVT, 4> ValueVTs;
1742-
ComputeValueVTs(TLI, DL, ReturnType, ValueVTs);
1743-
unsigned NumValues = ValueVTs.size();
1741+
SmallVector<Type *, 4> Types;
1742+
ComputeValueTypes(DL, ReturnType, Types);
1743+
unsigned NumValues = Types.size();
17441744
if (NumValues == 0) return;
17451745

1746-
for (unsigned j = 0, f = NumValues; j != f; ++j) {
1747-
EVT VT = ValueVTs[j];
1746+
for (Type *Ty : Types) {
1747+
EVT VT = TLI.getValueType(DL, Ty);
17481748
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
17491749

17501750
if (attr.hasRetAttr(Attribute::SExt))
@@ -1772,7 +1772,7 @@ void llvm::GetReturnInfo(CallingConv::ID CC, Type *ReturnType,
17721772
Flags.setZExt();
17731773

17741774
for (unsigned i = 0; i < NumParts; ++i)
1775-
Outs.push_back(ISD::OutputArg(Flags, PartVT, VT, ReturnType, 0, 0));
1775+
Outs.push_back(ISD::OutputArg(Flags, PartVT, VT, Ty, 0, 0));
17761776
}
17771777
}
17781778

0 commit comments

Comments
 (0)