-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[CallingConv] Return ArrayRef from AllocateRegBlock() (NFC) #124120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-arm Author: Nikita Popov (nikic) ChangesInstead of returning the first register, return the ArrayRef containing the whole block. Existing users rely on the fact that the register block only contains adjacently-numbered registers and it's possible to get the remaining registers in the block by just incrementing the register. Returning an ArrayRef allows more generic usage with non-adjacent registers. Full diff: https://github.com/llvm/llvm-project/pull/124120.diff 3 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h
index 85171138d1eb9d..7ad27cd01336a6 100644
--- a/llvm/include/llvm/CodeGen/CallingConvLower.h
+++ b/llvm/include/llvm/CodeGen/CallingConvLower.h
@@ -357,12 +357,13 @@ class CCState {
return Reg;
}
- /// AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive
- /// registers. If this is not possible, return zero. Otherwise, return the first
- /// register of the block that were allocated, marking the entire block as allocated.
- MCPhysReg AllocateRegBlock(ArrayRef<MCPhysReg> Regs, unsigned RegsRequired) {
+ /// Attempt to allocate a block of RegsRequired consecutive registers.
+ /// If this is not possible, return an empty range. Otherwise, return a
+ /// range of consecutive registers, marking the entire block as allocated.
+ ArrayRef<MCPhysReg> AllocateRegBlock(ArrayRef<MCPhysReg> Regs,
+ unsigned RegsRequired) {
if (RegsRequired > Regs.size())
- return 0;
+ return {};
for (unsigned StartIdx = 0; StartIdx <= Regs.size() - RegsRequired;
++StartIdx) {
@@ -379,11 +380,11 @@ class CCState {
for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) {
MarkAllocated(Regs[StartIdx + BlockIdx]);
}
- return Regs[StartIdx];
+ return Regs.slice(StartIdx, RegsRequired);
}
}
// No block was available
- return 0;
+ return {};
}
/// Version of AllocateReg with list of registers to be shadowed.
diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.cpp b/llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
index fa04ccfba30f06..991d710c979b9e 100644
--- a/llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
@@ -176,27 +176,27 @@ static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
// [N x i32] arguments get packed into x-registers on Darwin's arm64_32
// because that's how the armv7k Clang front-end emits small structs.
unsigned EltsPerReg = (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32) ? 2 : 1;
- unsigned RegResult = State.AllocateRegBlock(
+ ArrayRef<MCPhysReg> RegResult = State.AllocateRegBlock(
RegList, alignTo(PendingMembers.size(), EltsPerReg) / EltsPerReg);
- if (RegResult && EltsPerReg == 1) {
- for (auto &It : PendingMembers) {
- It.convertToReg(RegResult);
+ if (!RegResult.empty() && EltsPerReg == 1) {
+ for (const auto &[It, Reg] : zip(PendingMembers, RegResult)) {
+ It.convertToReg(Reg);
State.addLoc(It);
- ++RegResult;
}
PendingMembers.clear();
return true;
- } else if (RegResult) {
+ } else if (!RegResult.empty()) {
assert(EltsPerReg == 2 && "unexpected ABI");
bool UseHigh = false;
CCValAssign::LocInfo Info;
+ unsigned RegIdx = 0;
for (auto &It : PendingMembers) {
Info = UseHigh ? CCValAssign::AExtUpper : CCValAssign::ZExt;
- State.addLoc(CCValAssign::getReg(It.getValNo(), MVT::i32, RegResult,
- MVT::i64, Info));
+ State.addLoc(CCValAssign::getReg(It.getValNo(), MVT::i32,
+ RegResult[RegIdx], MVT::i64, Info));
UseHigh = !UseHigh;
if (!UseHigh)
- ++RegResult;
+ ++RegIdx;
}
PendingMembers.clear();
return true;
diff --git a/llvm/lib/Target/ARM/ARMCallingConv.cpp b/llvm/lib/Target/ARM/ARMCallingConv.cpp
index 5a88fff41aeb1d..2c429d7ea1a8b2 100644
--- a/llvm/lib/Target/ARM/ARMCallingConv.cpp
+++ b/llvm/lib/Target/ARM/ARMCallingConv.cpp
@@ -228,12 +228,11 @@ static bool CC_ARM_AAPCS_Custom_Aggregate(unsigned ValNo, MVT ValVT,
break;
}
- unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
- if (RegResult) {
- for (CCValAssign &PendingMember : PendingMembers) {
- PendingMember.convertToReg(RegResult);
+ ArrayRef<MCPhysReg> RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
+ if (!RegResult.empty()) {
+ for (const auto &[PendingMember, Reg] : zip(PendingMembers, RegResult)) {
+ PendingMember.convertToReg(Reg);
State.addLoc(PendingMember);
- ++RegResult;
}
PendingMembers.clear();
return true;
|
@llvm/pr-subscribers-backend-aarch64 Author: Nikita Popov (nikic) ChangesInstead of returning the first register, return the ArrayRef containing the whole block. Existing users rely on the fact that the register block only contains adjacently-numbered registers and it's possible to get the remaining registers in the block by just incrementing the register. Returning an ArrayRef allows more generic usage with non-adjacent registers. Full diff: https://github.com/llvm/llvm-project/pull/124120.diff 3 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h
index 85171138d1eb9d..7ad27cd01336a6 100644
--- a/llvm/include/llvm/CodeGen/CallingConvLower.h
+++ b/llvm/include/llvm/CodeGen/CallingConvLower.h
@@ -357,12 +357,13 @@ class CCState {
return Reg;
}
- /// AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive
- /// registers. If this is not possible, return zero. Otherwise, return the first
- /// register of the block that were allocated, marking the entire block as allocated.
- MCPhysReg AllocateRegBlock(ArrayRef<MCPhysReg> Regs, unsigned RegsRequired) {
+ /// Attempt to allocate a block of RegsRequired consecutive registers.
+ /// If this is not possible, return an empty range. Otherwise, return a
+ /// range of consecutive registers, marking the entire block as allocated.
+ ArrayRef<MCPhysReg> AllocateRegBlock(ArrayRef<MCPhysReg> Regs,
+ unsigned RegsRequired) {
if (RegsRequired > Regs.size())
- return 0;
+ return {};
for (unsigned StartIdx = 0; StartIdx <= Regs.size() - RegsRequired;
++StartIdx) {
@@ -379,11 +380,11 @@ class CCState {
for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) {
MarkAllocated(Regs[StartIdx + BlockIdx]);
}
- return Regs[StartIdx];
+ return Regs.slice(StartIdx, RegsRequired);
}
}
// No block was available
- return 0;
+ return {};
}
/// Version of AllocateReg with list of registers to be shadowed.
diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.cpp b/llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
index fa04ccfba30f06..991d710c979b9e 100644
--- a/llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.cpp
@@ -176,27 +176,27 @@ static bool CC_AArch64_Custom_Block(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
// [N x i32] arguments get packed into x-registers on Darwin's arm64_32
// because that's how the armv7k Clang front-end emits small structs.
unsigned EltsPerReg = (IsDarwinILP32 && LocVT.SimpleTy == MVT::i32) ? 2 : 1;
- unsigned RegResult = State.AllocateRegBlock(
+ ArrayRef<MCPhysReg> RegResult = State.AllocateRegBlock(
RegList, alignTo(PendingMembers.size(), EltsPerReg) / EltsPerReg);
- if (RegResult && EltsPerReg == 1) {
- for (auto &It : PendingMembers) {
- It.convertToReg(RegResult);
+ if (!RegResult.empty() && EltsPerReg == 1) {
+ for (const auto &[It, Reg] : zip(PendingMembers, RegResult)) {
+ It.convertToReg(Reg);
State.addLoc(It);
- ++RegResult;
}
PendingMembers.clear();
return true;
- } else if (RegResult) {
+ } else if (!RegResult.empty()) {
assert(EltsPerReg == 2 && "unexpected ABI");
bool UseHigh = false;
CCValAssign::LocInfo Info;
+ unsigned RegIdx = 0;
for (auto &It : PendingMembers) {
Info = UseHigh ? CCValAssign::AExtUpper : CCValAssign::ZExt;
- State.addLoc(CCValAssign::getReg(It.getValNo(), MVT::i32, RegResult,
- MVT::i64, Info));
+ State.addLoc(CCValAssign::getReg(It.getValNo(), MVT::i32,
+ RegResult[RegIdx], MVT::i64, Info));
UseHigh = !UseHigh;
if (!UseHigh)
- ++RegResult;
+ ++RegIdx;
}
PendingMembers.clear();
return true;
diff --git a/llvm/lib/Target/ARM/ARMCallingConv.cpp b/llvm/lib/Target/ARM/ARMCallingConv.cpp
index 5a88fff41aeb1d..2c429d7ea1a8b2 100644
--- a/llvm/lib/Target/ARM/ARMCallingConv.cpp
+++ b/llvm/lib/Target/ARM/ARMCallingConv.cpp
@@ -228,12 +228,11 @@ static bool CC_ARM_AAPCS_Custom_Aggregate(unsigned ValNo, MVT ValVT,
break;
}
- unsigned RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
- if (RegResult) {
- for (CCValAssign &PendingMember : PendingMembers) {
- PendingMember.convertToReg(RegResult);
+ ArrayRef<MCPhysReg> RegResult = State.AllocateRegBlock(RegList, PendingMembers.size());
+ if (!RegResult.empty()) {
+ for (const auto &[PendingMember, Reg] : zip(PendingMembers, RegResult)) {
+ PendingMember.convertToReg(Reg);
State.addLoc(PendingMember);
- ++RegResult;
}
PendingMembers.clear();
return true;
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Instead of returning the first register, return the ArrayRef containing the whole block. Existing users rely on the fact that the register block only contains adjacently-numbered registers and it's possible to get the remaining registers in the block by just incrementing the register. Returning an ArrayRef allows more generic usage with non-adjacent registers.
Instead of returning the first register, return the ArrayRef containing the whole block.
Existing users rely on the fact that the register block only contains adjacently-numbered registers and it's possible to get the remaining registers in the block by just incrementing the register. Returning an ArrayRef allows more generic usage with non-adjacent registers.