summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CallingConvLower.cpp
diff options
context:
space:
mode:
authorSergei Barannikov <barannikov88@gmail.com>2023-01-15 10:31:07 +0300
committerSergei Barannikov <s.barannikov@module.ru>2023-01-15 10:31:42 +0300
commitdca40e3288f481cda1ce37c647b782a3b468b7d1 (patch)
treed095af7c3206f35334e9b0ad950b7082da1133ab /llvm/lib/CodeGen/CallingConvLower.cpp
parentd8a2b295295e456a493166009b60c9480f123f2d (diff)
[CodeGen] Replace CCValAssign::Loc with std::variant (NFCI)
The motivation behind this change is as follows. Targets with stack growing up (there are no such in-tree targets) pass arguments at negative offsets relative to the stack pointer. This makes it hard to use the generic value assigner because CCValAssign stores the offset as an unsigned integer, which is then zero-extended when converted to int64_t, e.g. when passing to `CreateFixedObject`. This results in conversion of, for example, -4 into 4294967292, which is not desired. While it is possible to insert a cast to `int` before passing the result of `getLocMemOffset` into `CreateFixedObject` in backend code, this is error-prone, and some uses of `getLocMemOffset` are located in places common to all backends (e.g. `CallLowering::handleAssignments`). That said, I wanted to change the type of the memory offset from `unsigned` to `int64_t` (this would be consistent with other places where stack offsets are used). However, the `Loc` field which stores the offset is shared between three different kinds of the location: register, memory, and "pending". Storing a register number as `int64_t` does not seem right (there are `Register` and `MCRegister` for this), so I did the most straightforward change - replaced the `Loc` field with std::variant. The main change that changes the type of the memory offset from `unsigned` to `int64_t` will be in a follow-up patch to simplify the review. Reviewed By: MaskRay, nikic Differential Revision: https://reviews.llvm.org/D136043
Diffstat (limited to 'llvm/lib/CodeGen/CallingConvLower.cpp')
-rw-r--r--llvm/lib/CodeGen/CallingConvLower.cpp31
1 files changed, 16 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/CallingConvLower.cpp b/llvm/lib/CodeGen/CallingConvLower.cpp
index f49cc6427f06..ce1ef571c9df 100644
--- a/llvm/lib/CodeGen/CallingConvLower.cpp
+++ b/llvm/lib/CodeGen/CallingConvLower.cpp
@@ -231,7 +231,7 @@ void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs,
// when i64 and f64 are both passed in GPRs.
StackOffset = SavedStackOffset;
MaxStackArgAlign = SavedMaxStackArgAlign;
- Locs.resize(NumLocs);
+ Locs.truncate(NumLocs);
}
void CCState::analyzeMustTailForwardedRegisters(
@@ -270,19 +270,20 @@ bool CCState::resultsCompatible(CallingConv::ID CalleeCC,
CCState CCInfo2(CallerCC, false, MF, RVLocs2, C);
CCInfo2.AnalyzeCallResult(Ins, CallerFn);
- if (RVLocs1.size() != RVLocs2.size())
- return false;
- for (unsigned I = 0, E = RVLocs1.size(); I != E; ++I) {
- const CCValAssign &Loc1 = RVLocs1[I];
- const CCValAssign &Loc2 = RVLocs2[I];
-
- if ( // Must both be in registers, or both in memory
- Loc1.isRegLoc() != Loc2.isRegLoc() ||
- // Must fill the same part of their locations
- Loc1.getLocInfo() != Loc2.getLocInfo() ||
- // Memory offset/register number must be the same
- Loc1.getExtraInfo() != Loc2.getExtraInfo())
+ auto AreCompatible = [](const CCValAssign &Loc1, const CCValAssign &Loc2) {
+ assert(!Loc1.isPendingLoc() && !Loc2.isPendingLoc() &&
+ "The location must have been decided by now");
+ // Must fill the same part of their locations.
+ if (Loc1.getLocInfo() != Loc2.getLocInfo())
return false;
- }
- return true;
+ // Must both be in the same registers, or both in memory at the same offset.
+ if (Loc1.isRegLoc() && Loc2.isRegLoc())
+ return Loc1.getLocReg() == Loc2.getLocReg();
+ if (Loc1.isMemLoc() && Loc2.isMemLoc())
+ return Loc1.getLocMemOffset() == Loc2.getLocMemOffset();
+ llvm_unreachable("Unknown location kind");
+ };
+
+ return std::equal(RVLocs1.begin(), RVLocs1.end(), RVLocs2.begin(),
+ RVLocs2.end(), AreCompatible);
}