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