|
24 | 24 | #include "llvm/ADT/Statistic.h"
|
25 | 25 | #include "llvm/Analysis/MemoryLocation.h"
|
26 | 26 | #include "llvm/Analysis/VectorUtils.h"
|
| 27 | +#include "llvm/CodeGen/Analysis.h" |
27 | 28 | #include "llvm/CodeGen/MachineFrameInfo.h"
|
28 | 29 | #include "llvm/CodeGen/MachineFunction.h"
|
29 | 30 | #include "llvm/CodeGen/MachineInstrBuilder.h"
|
@@ -2240,6 +2241,22 @@ unsigned RISCVTargetLowering::combineRepeatedFPDivisors() const {
|
2240 | 2241 | return NumRepeatedDivisors;
|
2241 | 2242 | }
|
2242 | 2243 |
|
| 2244 | +bool RISCVTargetLowering::functionArgumentNeedsConsecutiveRegisters( |
| 2245 | + Type *Ty, CallingConv::ID CallConv, bool isVarArg, |
| 2246 | + const DataLayout &DL) const { |
| 2247 | + const bool IsPureCapABI = |
| 2248 | + RISCVABI::isCheriPureCapABI(Subtarget.getTargetABI()); |
| 2249 | + const bool HasBoundedVarArgs = |
| 2250 | + IsPureCapABI && Subtarget.hasCheriBoundVarArg(); |
| 2251 | + if (!Ty->isArrayTy()) |
| 2252 | + return false; |
| 2253 | + |
| 2254 | + // All non aggregate members of the type must have the same type |
| 2255 | + SmallVector<EVT> ValueVTs; |
| 2256 | + ComputeValueVTs(*this, DL, Ty, ValueVTs); |
| 2257 | + return all_equal(ValueVTs) && isVarArg && HasBoundedVarArgs; |
| 2258 | +} |
| 2259 | + |
2243 | 2260 | static SDValue getVLOperand(SDValue Op) {
|
2244 | 2261 | assert((Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
|
2245 | 2262 | Op.getOpcode() == ISD::INTRINSIC_W_CHAIN) &&
|
@@ -15361,6 +15378,37 @@ bool RISCV::CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
|
15361 | 15378 | if (ValVT.isFixedLengthVector())
|
15362 | 15379 | LocVT = TLI.getContainerForFixedLengthVector(LocVT);
|
15363 | 15380 |
|
| 15381 | + // For purecap bounded varargs - aggregate types which can fit into a stack |
| 15382 | + // slot are passed to CC_RISCV as separate arguments. We need to align the |
| 15383 | + // first argument to a CLEN alignment. |
| 15384 | + if (IsBoundedVarArgs && ArgFlags.isInConsecutiveRegs()) { |
| 15385 | + PendingLocs.push_back( |
| 15386 | + CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); |
| 15387 | + PendingArgFlags.push_back(ArgFlags); |
| 15388 | + if (!ArgFlags.isInConsecutiveRegsLast()) |
| 15389 | + return false; |
| 15390 | + } |
| 15391 | + |
| 15392 | + if (IsBoundedVarArgs && ArgFlags.isInConsecutiveRegsLast()) { |
| 15393 | + for (size_t I = 0, E = PendingLocs.size(); I < E; I++){ |
| 15394 | + CCValAssign VA = PendingLocs[I]; |
| 15395 | + unsigned Size = |
| 15396 | + VA.getValVT() == CLenVT ? DL.getPointerSize(200) : XLen / 8; |
| 15397 | + Align Alignment(Size); |
| 15398 | + // For consecutive types the first item needs to be aligned. |
| 15399 | + if (I == 0) |
| 15400 | + Alignment = Align(SlotSize); |
| 15401 | + |
| 15402 | + unsigned StackOffset = State.AllocateStack(Size, Alignment); |
| 15403 | + State.addLoc(CCValAssign::getMem(VA.getValNo(), VA.getValVT(), |
| 15404 | + StackOffset, VA.getLocVT(), |
| 15405 | + VA.getLocInfo())); |
| 15406 | + } |
| 15407 | + PendingLocs.clear(); |
| 15408 | + PendingArgFlags.clear(); |
| 15409 | + return false; |
| 15410 | + } |
| 15411 | + |
15364 | 15412 | // Split arguments might be passed indirectly, so keep track of the pending
|
15365 | 15413 | // values. Split vectors are passed via a mix of registers and indirectly, so
|
15366 | 15414 | // treat them as we would any other argument.
|
@@ -15440,15 +15488,9 @@ bool RISCV::CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
|
15440 | 15488 | Reg = State.AllocateReg(ArgGPRs);
|
15441 | 15489 | }
|
15442 | 15490 |
|
15443 |
| - // Aggregate types i.e. structs/arrays which can fit into 2*XLEN |
15444 |
| - // Don't allocate a slot for each instead we make sure that the next element |
15445 |
| - // is then properly aligned. |
15446 |
| - bool AllocateSlot = IsBoundedVarArgs; |
15447 |
| - if (OrigTy && OrigTy->isAggregateType()) |
15448 |
| - AllocateSlot = false; |
15449 | 15491 | unsigned StackOffset =
|
15450 | 15492 | Reg ? 0
|
15451 |
| - : (AllocateSlot |
| 15493 | + : (IsBoundedVarArgs |
15452 | 15494 | ? State.AllocateStack(SlotSize, Align(SlotSize))
|
15453 | 15495 | : State.AllocateStack(StoreSizeBytes, StackAlign));
|
15454 | 15496 |
|
@@ -16454,22 +16496,23 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
|
16454 | 16496 | SDValue Address =
|
16455 | 16497 | DAG.getPointerAdd(DL, StackPtr, VA.getLocMemOffset());
|
16456 | 16498 |
|
16457 |
| - if (UseBoundeMemArgsCaller && Outs[i].IsFixed) { |
| 16499 | + if (UseBoundeMemArgsCaller) { |
16458 | 16500 | if (FirstArgAddr == SDValue()) {
|
16459 | 16501 | FirstArgAddr = Address;
|
16460 | 16502 | MemArgStartOffset = VA.getLocMemOffset();
|
16461 | 16503 | }
|
16462 | 16504 | unsigned VTSize = VA.getValVT().getSizeInBits() / 8;
|
16463 | 16505 | MemArgEndOffset = VA.getLocMemOffset() + VTSize;
|
16464 | 16506 | }
|
| 16507 | + |
16465 | 16508 | if (UseBoundedVarArgs && !Outs[i].IsFixed) {
|
16466 | 16509 | if (FirstVAAddr == SDValue()) {
|
16467 | 16510 | FirstVAAddr = Address;
|
16468 | 16511 | VAArgStartOffset = VA.getLocMemOffset();
|
16469 | 16512 | }
|
16470 |
| - Align OffsetAlign = Align(PtrLenBytes); |
16471 | 16513 | unsigned VTSize = VA.getValVT().getSizeInBits() / 8;
|
16472 |
| - VAArgEndOffset = alignTo(VA.getLocMemOffset() + VTSize, OffsetAlign); |
| 16514 | + VAArgEndOffset = |
| 16515 | + alignTo(VA.getLocMemOffset() + VTSize, Align(PtrLenBytes)); |
16473 | 16516 | MemArgEndOffset = VAArgEndOffset;
|
16474 | 16517 | }
|
16475 | 16518 |
|
|
0 commit comments