forked from OSchip/llvm-project
GlobalISel: Early continue to reduce loop indentation
This commit is contained in:
parent
6dabd267bd
commit
a275acc4a9
|
@ -195,99 +195,100 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
|
|||
unsigned NumArgs = Args.size();
|
||||
for (unsigned i = 0; i != NumArgs; ++i) {
|
||||
EVT CurVT = EVT::getEVT(Args[i].Ty);
|
||||
if (!CurVT.isSimple() ||
|
||||
Handler.assignArg(i, CurVT.getSimpleVT(), CurVT.getSimpleVT(),
|
||||
CCValAssign::Full, Args[i], Args[i].Flags[0],
|
||||
CCInfo)) {
|
||||
MVT NewVT = TLI->getRegisterTypeForCallingConv(
|
||||
F.getContext(), F.getCallingConv(), EVT(CurVT));
|
||||
if (CurVT.isSimple() &&
|
||||
!Handler.assignArg(i, CurVT.getSimpleVT(), CurVT.getSimpleVT(),
|
||||
CCValAssign::Full, Args[i], Args[i].Flags[0],
|
||||
CCInfo))
|
||||
continue;
|
||||
|
||||
// If we need to split the type over multiple regs, check it's a scenario
|
||||
// we currently support.
|
||||
unsigned NumParts = TLI->getNumRegistersForCallingConv(
|
||||
F.getContext(), F.getCallingConv(), CurVT);
|
||||
if (NumParts > 1) {
|
||||
// For now only handle exact splits.
|
||||
if (NewVT.getSizeInBits() * NumParts != CurVT.getSizeInBits())
|
||||
MVT NewVT = TLI->getRegisterTypeForCallingConv(
|
||||
F.getContext(), F.getCallingConv(), EVT(CurVT));
|
||||
|
||||
// If we need to split the type over multiple regs, check it's a scenario
|
||||
// we currently support.
|
||||
unsigned NumParts = TLI->getNumRegistersForCallingConv(
|
||||
F.getContext(), F.getCallingConv(), CurVT);
|
||||
if (NumParts > 1) {
|
||||
// For now only handle exact splits.
|
||||
if (NewVT.getSizeInBits() * NumParts != CurVT.getSizeInBits())
|
||||
return false;
|
||||
}
|
||||
|
||||
// For incoming arguments (physregs to vregs), we could have values in
|
||||
// physregs (or memlocs) which we want to extract and copy to vregs.
|
||||
// During this, we might have to deal with the LLT being split across
|
||||
// multiple regs, so we have to record this information for later.
|
||||
//
|
||||
// If we have outgoing args, then we have the opposite case. We have a
|
||||
// vreg with an LLT which we want to assign to a physical location, and
|
||||
// we might have to record that the value has to be split later.
|
||||
if (Handler.isIncomingArgumentHandler()) {
|
||||
if (NumParts == 1) {
|
||||
// Try to use the register type if we couldn't assign the VT.
|
||||
if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
|
||||
Args[i].Flags[0], CCInfo))
|
||||
return false;
|
||||
}
|
||||
|
||||
// For incoming arguments (physregs to vregs), we could have values in
|
||||
// physregs (or memlocs) which we want to extract and copy to vregs.
|
||||
// During this, we might have to deal with the LLT being split across
|
||||
// multiple regs, so we have to record this information for later.
|
||||
//
|
||||
// If we have outgoing args, then we have the opposite case. We have a
|
||||
// vreg with an LLT which we want to assign to a physical location, and
|
||||
// we might have to record that the value has to be split later.
|
||||
if (Handler.isIncomingArgumentHandler()) {
|
||||
if (NumParts == 1) {
|
||||
// Try to use the register type if we couldn't assign the VT.
|
||||
if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
|
||||
Args[i].Flags[0], CCInfo))
|
||||
return false;
|
||||
} else {
|
||||
// We're handling an incoming arg which is split over multiple regs.
|
||||
// E.g. passing an s128 on AArch64.
|
||||
ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
|
||||
Args[i].OrigRegs.push_back(Args[i].Regs[0]);
|
||||
Args[i].Regs.clear();
|
||||
Args[i].Flags.clear();
|
||||
LLT NewLLT = getLLTForMVT(NewVT);
|
||||
// For each split register, create and assign a vreg that will store
|
||||
// the incoming component of the larger value. These will later be
|
||||
// merged to form the final vreg.
|
||||
for (unsigned Part = 0; Part < NumParts; ++Part) {
|
||||
Register Reg =
|
||||
MIRBuilder.getMRI()->createGenericVirtualRegister(NewLLT);
|
||||
ISD::ArgFlagsTy Flags = OrigFlags;
|
||||
if (Part == 0) {
|
||||
Flags.setSplit();
|
||||
} else {
|
||||
Flags.setOrigAlign(Align(1));
|
||||
if (Part == NumParts - 1)
|
||||
Flags.setSplitEnd();
|
||||
}
|
||||
Args[i].Regs.push_back(Reg);
|
||||
Args[i].Flags.push_back(Flags);
|
||||
if (Handler.assignArg(i + Part, NewVT, NewVT, CCValAssign::Full,
|
||||
Args[i], Args[i].Flags[Part], CCInfo)) {
|
||||
// Still couldn't assign this smaller part type for some reason.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Handling an outgoing arg that might need to be split.
|
||||
if (NumParts < 2)
|
||||
return false; // Don't know how to deal with this type combination.
|
||||
|
||||
// This type is passed via multiple registers in the calling convention.
|
||||
// We need to extract the individual parts.
|
||||
Register LargeReg = Args[i].Regs[0];
|
||||
LLT SmallTy = LLT::scalar(NewVT.getSizeInBits());
|
||||
auto Unmerge = MIRBuilder.buildUnmerge(SmallTy, LargeReg);
|
||||
assert(Unmerge->getNumOperands() == NumParts + 1);
|
||||
// We're handling an incoming arg which is split over multiple regs.
|
||||
// E.g. passing an s128 on AArch64.
|
||||
ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
|
||||
// We're going to replace the regs and flags with the split ones.
|
||||
Args[i].OrigRegs.push_back(Args[i].Regs[0]);
|
||||
Args[i].Regs.clear();
|
||||
Args[i].Flags.clear();
|
||||
for (unsigned PartIdx = 0; PartIdx < NumParts; ++PartIdx) {
|
||||
LLT NewLLT = getLLTForMVT(NewVT);
|
||||
// For each split register, create and assign a vreg that will store
|
||||
// the incoming component of the larger value. These will later be
|
||||
// merged to form the final vreg.
|
||||
for (unsigned Part = 0; Part < NumParts; ++Part) {
|
||||
Register Reg =
|
||||
MIRBuilder.getMRI()->createGenericVirtualRegister(NewLLT);
|
||||
ISD::ArgFlagsTy Flags = OrigFlags;
|
||||
if (PartIdx == 0) {
|
||||
if (Part == 0) {
|
||||
Flags.setSplit();
|
||||
} else {
|
||||
Flags.setOrigAlign(Align(1));
|
||||
if (PartIdx == NumParts - 1)
|
||||
if (Part == NumParts - 1)
|
||||
Flags.setSplitEnd();
|
||||
}
|
||||
Args[i].Regs.push_back(Unmerge.getReg(PartIdx));
|
||||
Args[i].Regs.push_back(Reg);
|
||||
Args[i].Flags.push_back(Flags);
|
||||
if (Handler.assignArg(i + PartIdx, NewVT, NewVT, CCValAssign::Full,
|
||||
Args[i], Args[i].Flags[PartIdx], CCInfo))
|
||||
if (Handler.assignArg(i + Part, NewVT, NewVT, CCValAssign::Full,
|
||||
Args[i], Args[i].Flags[Part], CCInfo)) {
|
||||
// Still couldn't assign this smaller part type for some reason.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Handling an outgoing arg that might need to be split.
|
||||
if (NumParts < 2)
|
||||
return false; // Don't know how to deal with this type combination.
|
||||
|
||||
// This type is passed via multiple registers in the calling convention.
|
||||
// We need to extract the individual parts.
|
||||
Register LargeReg = Args[i].Regs[0];
|
||||
LLT SmallTy = LLT::scalar(NewVT.getSizeInBits());
|
||||
auto Unmerge = MIRBuilder.buildUnmerge(SmallTy, LargeReg);
|
||||
assert(Unmerge->getNumOperands() == NumParts + 1);
|
||||
ISD::ArgFlagsTy OrigFlags = Args[i].Flags[0];
|
||||
// We're going to replace the regs and flags with the split ones.
|
||||
Args[i].Regs.clear();
|
||||
Args[i].Flags.clear();
|
||||
for (unsigned PartIdx = 0; PartIdx < NumParts; ++PartIdx) {
|
||||
ISD::ArgFlagsTy Flags = OrigFlags;
|
||||
if (PartIdx == 0) {
|
||||
Flags.setSplit();
|
||||
} else {
|
||||
Flags.setOrigAlign(Align(1));
|
||||
if (PartIdx == NumParts - 1)
|
||||
Flags.setSplitEnd();
|
||||
}
|
||||
Args[i].Regs.push_back(Unmerge.getReg(PartIdx));
|
||||
Args[i].Flags.push_back(Flags);
|
||||
if (Handler.assignArg(i + PartIdx, NewVT, NewVT, CCValAssign::Full,
|
||||
Args[i], Args[i].Flags[PartIdx], CCInfo))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue