Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 14 | pmbaty | 1 | //===- llvm/CallingConvLower.h - Calling Conventions ------------*- C++ -*-===// | 
| 2 | // | ||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| 4 | // See https://llvm.org/LICENSE.txt for license information. | ||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| 6 | // | ||
| 7 | //===----------------------------------------------------------------------===// | ||
| 8 | // | ||
| 9 | // This file declares the CCState and CCValAssign classes, used for lowering | ||
| 10 | // and implementing calling conventions. | ||
| 11 | // | ||
| 12 | //===----------------------------------------------------------------------===// | ||
| 13 | |||
| 14 | #ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H | ||
| 15 | #define LLVM_CODEGEN_CALLINGCONVLOWER_H | ||
| 16 | |||
| 17 | #include "llvm/ADT/SmallVector.h" | ||
| 18 | #include "llvm/CodeGen/Register.h" | ||
| 19 | #include "llvm/CodeGen/TargetCallingConv.h" | ||
| 20 | #include "llvm/IR/CallingConv.h" | ||
| 21 | #include "llvm/Support/Alignment.h" | ||
| 22 | |||
| 23 | namespace llvm { | ||
| 24 | |||
| 25 | class CCState; | ||
| 26 | class MachineFunction; | ||
| 27 | class MVT; | ||
| 28 | class TargetRegisterInfo; | ||
| 29 | |||
| 30 | /// CCValAssign - Represent assignment of one arg/retval to a location. | ||
| 31 | class CCValAssign { | ||
| 32 | public: | ||
| 33 | enum LocInfo { | ||
| 34 |     Full,      // The value fills the full location. | ||
| 35 |     SExt,      // The value is sign extended in the location. | ||
| 36 |     ZExt,      // The value is zero extended in the location. | ||
| 37 |     AExt,      // The value is extended with undefined upper bits. | ||
| 38 |     SExtUpper, // The value is in the upper bits of the location and should be | ||
| 39 |                // sign extended when retrieved. | ||
| 40 |     ZExtUpper, // The value is in the upper bits of the location and should be | ||
| 41 |                // zero extended when retrieved. | ||
| 42 |     AExtUpper, // The value is in the upper bits of the location and should be | ||
| 43 |                // extended with undefined upper bits when retrieved. | ||
| 44 |     BCvt,      // The value is bit-converted in the location. | ||
| 45 |     Trunc,     // The value is truncated in the location. | ||
| 46 |     VExt,      // The value is vector-widened in the location. | ||
| 47 |                // FIXME: Not implemented yet. Code that uses AExt to mean | ||
| 48 |                // vector-widen should be fixed to use VExt instead. | ||
| 49 |     FPExt,     // The floating-point value is fp-extended in the location. | ||
| 50 |     Indirect   // The location contains pointer to the value. | ||
| 51 |     // TODO: a subset of the value is in the location. | ||
| 52 | }; | ||
| 53 | |||
| 54 | private: | ||
| 55 |   // Holds one of: | ||
| 56 |   // - the register that the value is assigned to; | ||
| 57 |   // - the memory offset at which the value resides; | ||
| 58 |   // - additional information about pending location; the exact interpretation | ||
| 59 |   //   of the data is target-dependent. | ||
| 60 | std::variant<Register, int64_t, unsigned> Data; | ||
| 61 | |||
| 62 |   /// ValNo - This is the value number being assigned (e.g. an argument number). | ||
| 63 | unsigned ValNo; | ||
| 64 | |||
| 65 |   /// isCustom - True if this arg/retval requires special handling. | ||
| 66 | unsigned isCustom : 1; | ||
| 67 | |||
| 68 |   /// Information about how the value is assigned. | ||
| 69 | LocInfo HTP : 6; | ||
| 70 | |||
| 71 |   /// ValVT - The type of the value being assigned. | ||
| 72 |   MVT ValVT; | ||
| 73 | |||
| 74 |   /// LocVT - The type of the location being assigned to. | ||
| 75 |   MVT LocVT; | ||
| 76 | |||
| 77 | CCValAssign(LocInfo HTP, unsigned ValNo, MVT ValVT, MVT LocVT, bool IsCustom) | ||
| 78 | : ValNo(ValNo), isCustom(IsCustom), HTP(HTP), ValVT(ValVT), LocVT(LocVT) { | ||
| 79 |   } | ||
| 80 | |||
| 81 | public: | ||
| 82 | static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, | ||
| 83 | MVT LocVT, LocInfo HTP, bool IsCustom = false) { | ||
| 84 | CCValAssign Ret(HTP, ValNo, ValVT, LocVT, IsCustom); | ||
| 85 | Ret.Data = Register(RegNo); | ||
| 86 | return Ret; | ||
| 87 |   } | ||
| 88 | |||
| 89 | static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, | ||
| 90 | MVT LocVT, LocInfo HTP) { | ||
| 91 | return getReg(ValNo, ValVT, RegNo, LocVT, HTP, /*IsCustom=*/true); | ||
| 92 |   } | ||
| 93 | |||
| 94 | static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset, | ||
| 95 | MVT LocVT, LocInfo HTP, bool IsCustom = false) { | ||
| 96 | CCValAssign Ret(HTP, ValNo, ValVT, LocVT, IsCustom); | ||
| 97 | Ret.Data = int64_t(Offset); | ||
| 98 | return Ret; | ||
| 99 |   } | ||
| 100 | |||
| 101 | static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, unsigned Offset, | ||
| 102 | MVT LocVT, LocInfo HTP) { | ||
| 103 | return getMem(ValNo, ValVT, Offset, LocVT, HTP, /*IsCustom=*/true); | ||
| 104 |   } | ||
| 105 | |||
| 106 | static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, | ||
| 107 | LocInfo HTP, unsigned ExtraInfo = 0) { | ||
| 108 | CCValAssign Ret(HTP, ValNo, ValVT, LocVT, false); | ||
| 109 | Ret.Data = ExtraInfo; | ||
| 110 | return Ret; | ||
| 111 |   } | ||
| 112 | |||
| 113 | void convertToReg(unsigned RegNo) { Data = Register(RegNo); } | ||
| 114 | |||
| 115 | void convertToMem(unsigned Offset) { Data = int64_t(Offset); } | ||
| 116 | |||
| 117 | unsigned getValNo() const { return ValNo; } | ||
| 118 | MVT getValVT() const { return ValVT; } | ||
| 119 | |||
| 120 | bool isRegLoc() const { return std::holds_alternative<Register>(Data); } | ||
| 121 | bool isMemLoc() const { return std::holds_alternative<int64_t>(Data); } | ||
| 122 | bool isPendingLoc() const { return std::holds_alternative<unsigned>(Data); } | ||
| 123 | |||
| 124 | bool needsCustom() const { return isCustom; } | ||
| 125 | |||
| 126 | Register getLocReg() const { return std::get<Register>(Data); } | ||
| 127 | unsigned getLocMemOffset() const { return std::get<int64_t>(Data); } | ||
| 128 | unsigned getExtraInfo() const { return std::get<unsigned>(Data); } | ||
| 129 | |||
| 130 | MVT getLocVT() const { return LocVT; } | ||
| 131 | |||
| 132 | LocInfo getLocInfo() const { return HTP; } | ||
| 133 | bool isExtInLoc() const { | ||
| 134 | return (HTP == AExt || HTP == SExt || HTP == ZExt); | ||
| 135 |   } | ||
| 136 | |||
| 137 | bool isUpperBitsInLoc() const { | ||
| 138 | return HTP == AExtUpper || HTP == SExtUpper || HTP == ZExtUpper; | ||
| 139 |   } | ||
| 140 | }; | ||
| 141 | |||
| 142 | /// Describes a register that needs to be forwarded from the prologue to a | ||
| 143 | /// musttail call. | ||
| 144 | struct ForwardedRegister { | ||
| 145 | ForwardedRegister(Register VReg, MCPhysReg PReg, MVT VT) | ||
| 146 | : VReg(VReg), PReg(PReg), VT(VT) {} | ||
| 147 |   Register VReg; | ||
| 148 |   MCPhysReg PReg; | ||
| 149 |   MVT VT; | ||
| 150 | }; | ||
| 151 | |||
| 152 | /// CCAssignFn - This function assigns a location for Val, updating State to | ||
| 153 | /// reflect the change.  It returns 'true' if it failed to handle Val. | ||
| 154 | typedef bool CCAssignFn(unsigned ValNo, MVT ValVT, | ||
| 155 | MVT LocVT, CCValAssign::LocInfo LocInfo, | ||
| 156 | ISD::ArgFlagsTy ArgFlags, CCState &State); | ||
| 157 | |||
| 158 | /// CCCustomFn - This function assigns a location for Val, possibly updating | ||
| 159 | /// all args to reflect changes and indicates if it handled it. It must set | ||
| 160 | /// isCustom if it handles the arg and returns true. | ||
| 161 | typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT, | ||
| 162 | MVT &LocVT, CCValAssign::LocInfo &LocInfo, | ||
| 163 | ISD::ArgFlagsTy &ArgFlags, CCState &State); | ||
| 164 | |||
| 165 | /// CCState - This class holds information needed while lowering arguments and | ||
| 166 | /// return values.  It captures which registers are already assigned and which | ||
| 167 | /// stack slots are used.  It provides accessors to allocate these values. | ||
| 168 | class CCState { | ||
| 169 | private: | ||
| 170 | CallingConv::ID CallingConv; | ||
| 171 | bool IsVarArg; | ||
| 172 | bool AnalyzingMustTailForwardedRegs = false; | ||
| 173 | MachineFunction &MF; | ||
| 174 | const TargetRegisterInfo &TRI; | ||
| 175 | SmallVectorImpl<CCValAssign> &Locs; | ||
| 176 | LLVMContext &Context; | ||
| 177 | |||
| 178 | unsigned StackOffset; | ||
| 179 |   Align MaxStackArgAlign; | ||
| 180 | SmallVector<uint32_t, 16> UsedRegs; | ||
| 181 | SmallVector<CCValAssign, 4> PendingLocs; | ||
| 182 | SmallVector<ISD::ArgFlagsTy, 4> PendingArgFlags; | ||
| 183 | |||
| 184 |   // ByValInfo and SmallVector<ByValInfo, 4> ByValRegs: | ||
| 185 |   // | ||
| 186 |   // Vector of ByValInfo instances (ByValRegs) is introduced for byval registers | ||
| 187 |   // tracking. | ||
| 188 |   // Or, in another words it tracks byval parameters that are stored in | ||
| 189 |   // general purpose registers. | ||
| 190 |   // | ||
| 191 |   // For 4 byte stack alignment, | ||
| 192 |   // instance index means byval parameter number in formal | ||
| 193 |   // arguments set. Assume, we have some "struct_type" with size = 4 bytes, | ||
| 194 |   // then, for function "foo": | ||
| 195 |   // | ||
| 196 |   // i32 foo(i32 %p, %struct_type* %r, i32 %s, %struct_type* %t) | ||
| 197 |   // | ||
| 198 |   // ByValRegs[0] describes how "%r" is stored (Begin == r1, End == r2) | ||
| 199 |   // ByValRegs[1] describes how "%t" is stored (Begin == r3, End == r4). | ||
| 200 |   // | ||
| 201 |   // In case of 8 bytes stack alignment, | ||
| 202 |   // In function shown above, r3 would be wasted according to AAPCS rules. | ||
| 203 |   // ByValRegs vector size still would be 2, | ||
| 204 |   // while "%t" goes to the stack: it wouldn't be described in ByValRegs. | ||
| 205 |   // | ||
| 206 |   // Supposed use-case for this collection: | ||
| 207 |   // 1. Initially ByValRegs is empty, InRegsParamsProcessed is 0. | ||
| 208 |   // 2. HandleByVal fills up ByValRegs. | ||
| 209 |   // 3. Argument analysis (LowerFormatArguments, for example). After | ||
| 210 |   // some byval argument was analyzed, InRegsParamsProcessed is increased. | ||
| 211 | struct ByValInfo { | ||
| 212 | ByValInfo(unsigned B, unsigned E) : Begin(B), End(E) {} | ||
| 213 | |||
| 214 |     // First register allocated for current parameter. | ||
| 215 | unsigned Begin; | ||
| 216 | |||
| 217 |     // First after last register allocated for current parameter. | ||
| 218 | unsigned End; | ||
| 219 | }; | ||
| 220 | SmallVector<ByValInfo, 4 > ByValRegs; | ||
| 221 | |||
| 222 |   // InRegsParamsProcessed - shows how many instances of ByValRegs was proceed | ||
| 223 |   // during argument analysis. | ||
| 224 | unsigned InRegsParamsProcessed; | ||
| 225 | |||
| 226 | public: | ||
| 227 | CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, | ||
| 228 | SmallVectorImpl<CCValAssign> &locs, LLVMContext &C); | ||
| 229 | |||
| 230 | void addLoc(const CCValAssign &V) { | ||
| 231 | Locs.push_back(V); | ||
| 232 |   } | ||
| 233 | |||
| 234 | LLVMContext &getContext() const { return Context; } | ||
| 235 | MachineFunction &getMachineFunction() const { return MF; } | ||
| 236 | CallingConv::ID getCallingConv() const { return CallingConv; } | ||
| 237 | bool isVarArg() const { return IsVarArg; } | ||
| 238 | |||
| 239 |   /// getNextStackOffset - Return the next stack offset such that all stack | ||
| 240 |   /// slots satisfy their alignment requirements. | ||
| 241 | unsigned getNextStackOffset() const { | ||
| 242 | return StackOffset; | ||
| 243 |   } | ||
| 244 | |||
| 245 |   /// getAlignedCallFrameSize - Return the size of the call frame needed to | ||
| 246 |   /// be able to store all arguments and such that the alignment requirement | ||
| 247 |   /// of each of the arguments is satisfied. | ||
| 248 | unsigned getAlignedCallFrameSize() const { | ||
| 249 | return alignTo(StackOffset, MaxStackArgAlign); | ||
| 250 |   } | ||
| 251 | |||
| 252 |   /// isAllocated - Return true if the specified register (or an alias) is | ||
| 253 |   /// allocated. | ||
| 254 | bool isAllocated(MCRegister Reg) const { | ||
| 255 | return UsedRegs[Reg / 32] & (1 << (Reg & 31)); | ||
| 256 |   } | ||
| 257 | |||
| 258 |   /// AnalyzeFormalArguments - Analyze an array of argument values, | ||
| 259 |   /// incorporating info about the formals into this state. | ||
| 260 | void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, | ||
| 261 | CCAssignFn Fn); | ||
| 262 | |||
| 263 |   /// The function will invoke AnalyzeFormalArguments. | ||
| 264 | void AnalyzeArguments(const SmallVectorImpl<ISD::InputArg> &Ins, | ||
| 265 | CCAssignFn Fn) { | ||
| 266 | AnalyzeFormalArguments(Ins, Fn); | ||
| 267 |   } | ||
| 268 | |||
| 269 |   /// AnalyzeReturn - Analyze the returned values of a return, | ||
| 270 |   /// incorporating info about the result values into this state. | ||
| 271 | void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, | ||
| 272 | CCAssignFn Fn); | ||
| 273 | |||
| 274 |   /// CheckReturn - Analyze the return values of a function, returning | ||
| 275 |   /// true if the return can be performed without sret-demotion, and | ||
| 276 |   /// false otherwise. | ||
| 277 | bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, | ||
| 278 | CCAssignFn Fn); | ||
| 279 | |||
| 280 |   /// AnalyzeCallOperands - Analyze the outgoing arguments to a call, | ||
| 281 |   /// incorporating info about the passed values into this state. | ||
| 282 | void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, | ||
| 283 | CCAssignFn Fn); | ||
| 284 | |||
| 285 |   /// AnalyzeCallOperands - Same as above except it takes vectors of types | ||
| 286 |   /// and argument flags. | ||
| 287 | void AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs, | ||
| 288 | SmallVectorImpl<ISD::ArgFlagsTy> &Flags, | ||
| 289 | CCAssignFn Fn); | ||
| 290 | |||
| 291 |   /// The function will invoke AnalyzeCallOperands. | ||
| 292 | void AnalyzeArguments(const SmallVectorImpl<ISD::OutputArg> &Outs, | ||
| 293 | CCAssignFn Fn) { | ||
| 294 | AnalyzeCallOperands(Outs, Fn); | ||
| 295 |   } | ||
| 296 | |||
| 297 |   /// AnalyzeCallResult - Analyze the return values of a call, | ||
| 298 |   /// incorporating info about the passed values into this state. | ||
| 299 | void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, | ||
| 300 | CCAssignFn Fn); | ||
| 301 | |||
| 302 |   /// A shadow allocated register is a register that was allocated | ||
| 303 |   /// but wasn't added to the location list (Locs). | ||
| 304 |   /// \returns true if the register was allocated as shadow or false otherwise. | ||
| 305 | bool IsShadowAllocatedReg(MCRegister Reg) const; | ||
| 306 | |||
| 307 |   /// AnalyzeCallResult - Same as above except it's specialized for calls which | ||
| 308 |   /// produce a single value. | ||
| 309 | void AnalyzeCallResult(MVT VT, CCAssignFn Fn); | ||
| 310 | |||
| 311 |   /// getFirstUnallocated - Return the index of the first unallocated register | ||
| 312 |   /// in the set, or Regs.size() if they are all allocated. | ||
| 313 | unsigned getFirstUnallocated(ArrayRef<MCPhysReg> Regs) const { | ||
| 314 | for (unsigned i = 0; i < Regs.size(); ++i) | ||
| 315 | if (!isAllocated(Regs[i])) | ||
| 316 | return i; | ||
| 317 | return Regs.size(); | ||
| 318 |   } | ||
| 319 | |||
| 320 | void DeallocateReg(MCPhysReg Reg) { | ||
| 321 | assert(isAllocated(Reg) && "Trying to deallocate an unallocated register"); | ||
| 322 | MarkUnallocated(Reg); | ||
| 323 |   } | ||
| 324 | |||
| 325 |   /// AllocateReg - Attempt to allocate one register.  If it is not available, | ||
| 326 |   /// return zero.  Otherwise, return the register, marking it and any aliases | ||
| 327 |   /// as allocated. | ||
| 328 | MCRegister AllocateReg(MCPhysReg Reg) { | ||
| 329 | if (isAllocated(Reg)) | ||
| 330 | return MCRegister(); | ||
| 331 | MarkAllocated(Reg); | ||
| 332 | return Reg; | ||
| 333 |   } | ||
| 334 | |||
| 335 |   /// Version of AllocateReg with extra register to be shadowed. | ||
| 336 | MCRegister AllocateReg(MCPhysReg Reg, MCPhysReg ShadowReg) { | ||
| 337 | if (isAllocated(Reg)) | ||
| 338 | return MCRegister(); | ||
| 339 | MarkAllocated(Reg); | ||
| 340 | MarkAllocated(ShadowReg); | ||
| 341 | return Reg; | ||
| 342 |   } | ||
| 343 | |||
| 344 |   /// AllocateReg - Attempt to allocate one of the specified registers.  If none | ||
| 345 |   /// are available, return zero.  Otherwise, return the first one available, | ||
| 346 |   /// marking it and any aliases as allocated. | ||
| 347 | MCPhysReg AllocateReg(ArrayRef<MCPhysReg> Regs) { | ||
| 348 | unsigned FirstUnalloc = getFirstUnallocated(Regs); | ||
| 349 | if (FirstUnalloc == Regs.size()) | ||
| 350 | return MCRegister(); // Didn't find the reg. | ||
| 351 | |||
| 352 |     // Mark the register and any aliases as allocated. | ||
| 353 | MCPhysReg Reg = Regs[FirstUnalloc]; | ||
| 354 | MarkAllocated(Reg); | ||
| 355 | return Reg; | ||
| 356 |   } | ||
| 357 | |||
| 358 |   /// AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive | ||
| 359 |   /// registers. If this is not possible, return zero. Otherwise, return the first | ||
| 360 |   /// register of the block that were allocated, marking the entire block as allocated. | ||
| 361 | MCPhysReg AllocateRegBlock(ArrayRef<MCPhysReg> Regs, unsigned RegsRequired) { | ||
| 362 | if (RegsRequired > Regs.size()) | ||
| 363 | return 0; | ||
| 364 | |||
| 365 | for (unsigned StartIdx = 0; StartIdx <= Regs.size() - RegsRequired; | ||
| 366 | ++StartIdx) { | ||
| 367 | bool BlockAvailable = true; | ||
| 368 |       // Check for already-allocated regs in this block | ||
| 369 | for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) { | ||
| 370 | if (isAllocated(Regs[StartIdx + BlockIdx])) { | ||
| 371 | BlockAvailable = false; | ||
| 372 | break; | ||
| 373 |         } | ||
| 374 |       } | ||
| 375 | if (BlockAvailable) { | ||
| 376 |         // Mark the entire block as allocated | ||
| 377 | for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) { | ||
| 378 | MarkAllocated(Regs[StartIdx + BlockIdx]); | ||
| 379 |         } | ||
| 380 | return Regs[StartIdx]; | ||
| 381 |       } | ||
| 382 |     } | ||
| 383 |     // No block was available | ||
| 384 | return 0; | ||
| 385 |   } | ||
| 386 | |||
| 387 |   /// Version of AllocateReg with list of registers to be shadowed. | ||
| 388 | MCRegister AllocateReg(ArrayRef<MCPhysReg> Regs, const MCPhysReg *ShadowRegs) { | ||
| 389 | unsigned FirstUnalloc = getFirstUnallocated(Regs); | ||
| 390 | if (FirstUnalloc == Regs.size()) | ||
| 391 | return MCRegister(); // Didn't find the reg. | ||
| 392 | |||
| 393 |     // Mark the register and any aliases as allocated. | ||
| 394 | MCRegister Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc]; | ||
| 395 | MarkAllocated(Reg); | ||
| 396 | MarkAllocated(ShadowReg); | ||
| 397 | return Reg; | ||
| 398 |   } | ||
| 399 | |||
| 400 |   /// AllocateStack - Allocate a chunk of stack space with the specified size | ||
| 401 |   /// and alignment. | ||
| 402 | unsigned AllocateStack(unsigned Size, Align Alignment) { | ||
| 403 | StackOffset = alignTo(StackOffset, Alignment); | ||
| 404 | unsigned Result = StackOffset; | ||
| 405 | StackOffset += Size; | ||
| 406 | MaxStackArgAlign = std::max(Alignment, MaxStackArgAlign); | ||
| 407 | ensureMaxAlignment(Alignment); | ||
| 408 | return Result; | ||
| 409 |   } | ||
| 410 | |||
| 411 | void ensureMaxAlignment(Align Alignment); | ||
| 412 | |||
| 413 |   /// Version of AllocateStack with list of extra registers to be shadowed. | ||
| 414 |   /// Note that, unlike AllocateReg, this shadows ALL of the shadow registers. | ||
| 415 | unsigned AllocateStack(unsigned Size, Align Alignment, | ||
| 416 | ArrayRef<MCPhysReg> ShadowRegs) { | ||
| 417 | for (MCPhysReg Reg : ShadowRegs) | ||
| 418 | MarkAllocated(Reg); | ||
| 419 | return AllocateStack(Size, Alignment); | ||
| 420 |   } | ||
| 421 | |||
| 422 |   // HandleByVal - Allocate a stack slot large enough to pass an argument by | ||
| 423 |   // value. The size and alignment information of the argument is encoded in its | ||
| 424 |   // parameter attribute. | ||
| 425 | void HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT, | ||
| 426 | CCValAssign::LocInfo LocInfo, int MinSize, Align MinAlign, | ||
| 427 | ISD::ArgFlagsTy ArgFlags); | ||
| 428 | |||
| 429 |   // Returns count of byval arguments that are to be stored (even partly) | ||
| 430 |   // in registers. | ||
| 431 | unsigned getInRegsParamsCount() const { return ByValRegs.size(); } | ||
| 432 | |||
| 433 |   // Returns count of byval in-regs arguments processed. | ||
| 434 | unsigned getInRegsParamsProcessed() const { return InRegsParamsProcessed; } | ||
| 435 | |||
| 436 |   // Get information about N-th byval parameter that is stored in registers. | ||
| 437 |   // Here "ByValParamIndex" is N. | ||
| 438 | void getInRegsParamInfo(unsigned InRegsParamRecordIndex, | ||
| 439 | unsigned& BeginReg, unsigned& EndReg) const { | ||
| 440 | assert(InRegsParamRecordIndex < ByValRegs.size() && | ||
| 441 | "Wrong ByVal parameter index"); | ||
| 442 | |||
| 443 | const ByValInfo& info = ByValRegs[InRegsParamRecordIndex]; | ||
| 444 | BeginReg = info.Begin; | ||
| 445 | EndReg = info.End; | ||
| 446 |   } | ||
| 447 | |||
| 448 |   // Add information about parameter that is kept in registers. | ||
| 449 | void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd) { | ||
| 450 | ByValRegs.push_back(ByValInfo(RegBegin, RegEnd)); | ||
| 451 |   } | ||
| 452 | |||
| 453 |   // Goes either to next byval parameter (excluding "waste" record), or | ||
| 454 |   // to the end of collection. | ||
| 455 |   // Returns false, if end is reached. | ||
| 456 | bool nextInRegsParam() { | ||
| 457 | unsigned e = ByValRegs.size(); | ||
| 458 | if (InRegsParamsProcessed < e) | ||
| 459 | ++InRegsParamsProcessed; | ||
| 460 | return InRegsParamsProcessed < e; | ||
| 461 |   } | ||
| 462 | |||
| 463 |   // Clear byval registers tracking info. | ||
| 464 | void clearByValRegsInfo() { | ||
| 465 | InRegsParamsProcessed = 0; | ||
| 466 | ByValRegs.clear(); | ||
| 467 |   } | ||
| 468 | |||
| 469 |   // Rewind byval registers tracking info. | ||
| 470 | void rewindByValRegsInfo() { | ||
| 471 | InRegsParamsProcessed = 0; | ||
| 472 |   } | ||
| 473 | |||
| 474 |   // Get list of pending assignments | ||
| 475 | SmallVectorImpl<CCValAssign> &getPendingLocs() { | ||
| 476 | return PendingLocs; | ||
| 477 |   } | ||
| 478 | |||
| 479 |   // Get a list of argflags for pending assignments. | ||
| 480 | SmallVectorImpl<ISD::ArgFlagsTy> &getPendingArgFlags() { | ||
| 481 | return PendingArgFlags; | ||
| 482 |   } | ||
| 483 | |||
| 484 |   /// Compute the remaining unused register parameters that would be used for | ||
| 485 |   /// the given value type. This is useful when varargs are passed in the | ||
| 486 |   /// registers that normal prototyped parameters would be passed in, or for | ||
| 487 |   /// implementing perfect forwarding. | ||
| 488 | void getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs, MVT VT, | ||
| 489 | CCAssignFn Fn); | ||
| 490 | |||
| 491 |   /// Compute the set of registers that need to be preserved and forwarded to | ||
| 492 |   /// any musttail calls. | ||
| 493 | void analyzeMustTailForwardedRegisters( | ||
| 494 | SmallVectorImpl<ForwardedRegister> &Forwards, ArrayRef<MVT> RegParmTypes, | ||
| 495 | CCAssignFn Fn); | ||
| 496 | |||
| 497 |   /// Returns true if the results of the two calling conventions are compatible. | ||
| 498 |   /// This is usually part of the check for tailcall eligibility. | ||
| 499 | static bool resultsCompatible(CallingConv::ID CalleeCC, | ||
| 500 | CallingConv::ID CallerCC, MachineFunction &MF, | ||
| 501 |                                 LLVMContext &C, | ||
| 502 | const SmallVectorImpl<ISD::InputArg> &Ins, | ||
| 503 | CCAssignFn CalleeFn, CCAssignFn CallerFn); | ||
| 504 | |||
| 505 |   /// The function runs an additional analysis pass over function arguments. | ||
| 506 |   /// It will mark each argument with the attribute flag SecArgPass. | ||
| 507 |   /// After running, it will sort the locs list. | ||
| 508 | template <class T> | ||
| 509 | void AnalyzeArgumentsSecondPass(const SmallVectorImpl<T> &Args, | ||
| 510 | CCAssignFn Fn) { | ||
| 511 | unsigned NumFirstPassLocs = Locs.size(); | ||
| 512 | |||
| 513 |     /// Creates similar argument list to \p Args in which each argument is | ||
| 514 |     /// marked using SecArgPass flag. | ||
| 515 | SmallVector<T, 16> SecPassArg; | ||
| 516 |     // SmallVector<ISD::InputArg, 16> SecPassArg; | ||
| 517 | for (auto Arg : Args) { | ||
| 518 | Arg.Flags.setSecArgPass(); | ||
| 519 | SecPassArg.push_back(Arg); | ||
| 520 |     } | ||
| 521 | |||
| 522 |     // Run the second argument pass | ||
| 523 | AnalyzeArguments(SecPassArg, Fn); | ||
| 524 | |||
| 525 |     // Sort the locations of the arguments according to their original position. | ||
| 526 | SmallVector<CCValAssign, 16> TmpArgLocs; | ||
| 527 | TmpArgLocs.swap(Locs); | ||
| 528 | auto B = TmpArgLocs.begin(), E = TmpArgLocs.end(); | ||
| 529 | std::merge(B, B + NumFirstPassLocs, B + NumFirstPassLocs, E, | ||
| 530 | std::back_inserter(Locs), | ||
| 531 | [](const CCValAssign &A, const CCValAssign &B) -> bool { | ||
| 532 | return A.getValNo() < B.getValNo(); | ||
| 533 | }); | ||
| 534 |   } | ||
| 535 | |||
| 536 | private: | ||
| 537 |   /// MarkAllocated - Mark a register and all of its aliases as allocated. | ||
| 538 | void MarkAllocated(MCPhysReg Reg); | ||
| 539 | |||
| 540 | void MarkUnallocated(MCPhysReg Reg); | ||
| 541 | }; | ||
| 542 | |||
| 543 | } // end namespace llvm | ||
| 544 | |||
| 545 | #endif // LLVM_CODEGEN_CALLINGCONVLOWER_H |