LLVM: include/llvm/CodeGen/CallingConvLower.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14#ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H

15#define LLVM_CODEGEN_CALLINGCONVLOWER_H

16

23#include

24

25namespace llvm {

26

27class CCState;

28class MachineFunction;

29class MVT;

30class TargetRegisterInfo;

31

32

34public:

36 Full,

37 SExt,

38 ZExt,

39 AExt,

40 SExtUpper,

41

42 ZExtUpper,

43

44 AExtUpper,

45

46 BCvt,

47 Trunc,

48 VExt,

49

50

51 FPExt,

52 Indirect

53

55

56private:

57

58

59

60

61

62 std::variant<Register, int64_t, unsigned> Data;

63

64

65 unsigned ValNo;

66

67

68 unsigned isCustom : 1;

69

70

72

73

74 MVT ValVT;

75

76

77 MVT LocVT;

78

80 : ValNo(ValNo), isCustom(IsCustom), HTP(HTP), ValVT(ValVT), LocVT(LocVT) {

81 }

82

83public:

85 MVT LocVT, LocInfo HTP, bool IsCustom = false) {

86 CCValAssign Ret(HTP, ValNo, ValVT, LocVT, IsCustom);

88 return Ret;

89 }

90

93 return getReg(ValNo, ValVT, Reg, LocVT, HTP, true);

94 }

95

97 MVT LocVT, LocInfo HTP, bool IsCustom = false) {

98 CCValAssign Ret(HTP, ValNo, ValVT, LocVT, IsCustom);

100 return Ret;

101 }

102

105 return getMem(ValNo, ValVT, Offset, LocVT, HTP, true);

106 }

107

109 LocInfo HTP, unsigned ExtraInfo = 0) {

110 CCValAssign Ret(HTP, ValNo, ValVT, LocVT, false);

111 Ret.Data = ExtraInfo;

112 return Ret;

113 }

114

116

118

119 unsigned getValNo() const { return ValNo; }

121

122 bool isRegLoc() const { return std::holds_alternative(Data); }

123 bool isMemLoc() const { return std::holds_alternative<int64_t>(Data); }

124 bool isPendingLoc() const { return std::holds_alternative(Data); }

125

127

130 unsigned getExtraInfo() const { return std::get(Data); }

131

133

136 return (HTP == AExt || HTP == SExt || HTP == ZExt);

137 }

138

141 }

142};

143

144

145

152};

153

154

155

159

160

161

162

166

167

168

169

171private:

173 bool IsVarArg;

174 bool AnalyzingMustTailForwardedRegs = false;

179

180 bool NegativeOffsets;

181

183 Align MaxStackArgAlign;

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215 struct ByValInfo {

216 ByValInfo(unsigned B, unsigned E) : Begin(B), End(E) {}

217

218

219 unsigned Begin;

220

221

222 unsigned End;

223 };

225

226

227

228 unsigned InRegsParamsProcessed;

229

230public:

233 bool NegativeOffsets = false);

234

237 }

238

242 bool isVarArg() const { return IsVarArg; }

243

244

246

247

248

249

251 return alignTo(StackSize, MaxStackArgAlign);

252 }

253

254

255

257 return UsedRegs[Reg.id() / 32] & (1 << (Reg.id() & 31));

258 }

259

260

261

264

265

269 }

270

271

272

275

276

277

278

281

282

283

286

287

288

292

293

297 }

298

299

300

303

304

305

306

308

309

310

312

313

314

316 for (unsigned i = 0; i < Regs.size(); ++i)

318 return i;

319 return Regs.size();

320 }

321

324 MarkUnallocated(Reg);

325 }

326

327

328

329

333 MarkAllocated(Reg);

334 return Reg;

335 }

336

337

341 MarkAllocated(Reg);

342 MarkAllocated(ShadowReg);

343 return Reg;

344 }

345

346

347

348

351 if (FirstUnalloc == Regs.size())

352 return MCRegister();

353

354

356 MarkAllocated(Reg);

357 return Reg;

358 }

359

360

361

362

364 if (RegsRequired > Regs.size())

365 return 0;

366

367 for (unsigned StartIdx = 0; StartIdx <= Regs.size() - RegsRequired;

368 ++StartIdx) {

369 bool BlockAvailable = true;

370

371 for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) {

372 if (isAllocated(Regs[StartIdx + BlockIdx])) {

373 BlockAvailable = false;

374 break;

375 }

376 }

377 if (BlockAvailable) {

378

379 for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) {

380 MarkAllocated(Regs[StartIdx + BlockIdx]);

381 }

382 return Regs[StartIdx];

383 }

384 }

385

386 return 0;

387 }

388

389

392 if (FirstUnalloc == Regs.size())

393 return MCRegister();

394

395

396 MCRegister Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc];

397 MarkAllocated(Reg);

398 MarkAllocated(ShadowReg);

399 return Reg;

400 }

401

402

403

406 if (NegativeOffsets) {

407 StackSize = alignTo(StackSize + Size, Alignment);

409 } else {

412 }

413 MaxStackArgAlign = std::max(Alignment, MaxStackArgAlign);

416 }

417

419

420

421

425 MarkAllocated(Reg);

427 }

428

429

430

431

435

436

437

439

440

442

443

444

446 unsigned& BeginReg, unsigned& EndReg) const {

447 assert(InRegsParamRecordIndex < ByValRegs.size() &&

448 "Wrong ByVal parameter index");

449

450 const ByValInfo& info = ByValRegs[InRegsParamRecordIndex];

451 BeginReg = info.Begin;

452 EndReg = info.End;

453 }

454

455

457 ByValRegs.push_back(ByValInfo(RegBegin, RegEnd));

458 }

459

460

461

462

464 unsigned e = ByValRegs.size();

465 if (InRegsParamsProcessed < e)

466 ++InRegsParamsProcessed;

467 return InRegsParamsProcessed < e;

468 }

469

470

472 InRegsParamsProcessed = 0;

473 ByValRegs.clear();

474 }

475

476

478 InRegsParamsProcessed = 0;

479 }

480

481

483 return PendingLocs;

484 }

485

486

488 return PendingArgFlags;

489 }

490

491

492

493

494

497

498

499

503

504

505

511

512

513

514

515 template

518 unsigned NumFirstPassLocs = Locs.size();

519

520

521

523

524 for (auto Arg : Args) {

525 Arg.Flags.setSecArgPass();

527 }

528

529

531

532

534 TmpArgLocs.swap(Locs);

535 auto B = TmpArgLocs.begin(), E = TmpArgLocs.end();

536 std::merge(B, B + NumFirstPassLocs, B + NumFirstPassLocs, E,

537 std::back_inserter(Locs),

539 return A.getValNo() < B.getValNo();

540 });

541 }

542

543private:

544

546

548};

549

550}

551

552#endif

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallVector class.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

CCState - This class holds information needed while lowering arguments and return values.

void getInRegsParamInfo(unsigned InRegsParamRecordIndex, unsigned &BeginReg, unsigned &EndReg) const

void HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, int MinSize, Align MinAlign, ISD::ArgFlagsTy ArgFlags)

Allocate space on the stack large enough to pass an argument by value.

MachineFunction & getMachineFunction() const

unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const

getFirstUnallocated - Return the index of the first unallocated register in the set,...

void AnalyzeArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)

The function will invoke AnalyzeFormalArguments.

void analyzeMustTailForwardedRegisters(SmallVectorImpl< ForwardedRegister > &Forwards, ArrayRef< MVT > RegParmTypes, CCAssignFn Fn)

Compute the set of registers that need to be preserved and forwarded to any musttail calls.

int64_t AllocateStack(unsigned Size, Align Alignment, ArrayRef< MCPhysReg > ShadowRegs)

Version of AllocateStack with list of extra registers to be shadowed.

void AnalyzeArgumentsSecondPass(const SmallVectorImpl< T > &Args, CCAssignFn Fn)

The function runs an additional analysis pass over function arguments.

static bool resultsCompatible(CallingConv::ID CalleeCC, CallingConv::ID CallerCC, MachineFunction &MF, LLVMContext &C, const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn CalleeFn, CCAssignFn CallerFn)

Returns true if the results of the two calling conventions are compatible.

MCRegister AllocateReg(ArrayRef< MCPhysReg > Regs)

AllocateReg - Attempt to allocate one of the specified registers.

void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)

AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...

bool IsShadowAllocatedReg(MCRegister Reg) const

A shadow allocated register is a register that was allocated but wasn't added to the location list (L...

void AnalyzeArguments(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)

The function will invoke AnalyzeCallOperands.

CallingConv::ID getCallingConv() const

SmallVectorImpl< ISD::ArgFlagsTy > & getPendingArgFlags()

MCRegister AllocateReg(MCPhysReg Reg)

AllocateReg - Attempt to allocate one register.

bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)

CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...

MCPhysReg AllocateRegBlock(ArrayRef< MCPhysReg > Regs, unsigned RegsRequired)

AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive registers.

void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)

AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...

LLVMContext & getContext() const

int64_t AllocateStack(unsigned Size, Align Alignment)

AllocateStack - Allocate a chunk of stack space with the specified size and alignment.

void rewindByValRegsInfo()

void getRemainingRegParmsForType(SmallVectorImpl< MCPhysReg > &Regs, MVT VT, CCAssignFn Fn)

Compute the remaining unused register parameters that would be used for the given value type.

void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)

AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...

unsigned getInRegsParamsProcessed() const

void ensureMaxAlignment(Align Alignment)

void DeallocateReg(MCPhysReg Reg)

uint64_t getStackSize() const

Returns the size of the currently allocated portion of the stack.

MCRegister AllocateReg(ArrayRef< MCPhysReg > Regs, const MCPhysReg *ShadowRegs)

Version of AllocateReg with list of registers to be shadowed.

SmallVectorImpl< CCValAssign > & getPendingLocs()

uint64_t getAlignedCallFrameSize() const

getAlignedCallFrameSize - Return the size of the call frame needed to be able to store all arguments ...

bool isAllocated(MCRegister Reg) const

isAllocated - Return true if the specified register (or an alias) is allocated.

void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd)

MCRegister AllocateReg(MCPhysReg Reg, MCPhysReg ShadowReg)

Version of AllocateReg with extra register to be shadowed.

void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)

AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...

void addLoc(const CCValAssign &V)

unsigned getInRegsParamsCount() const

void clearByValRegsInfo()

CCValAssign - Represent assignment of one arg/retval to a location.

void convertToReg(MCRegister Reg)

static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)

Register getLocReg() const

bool isPendingLoc() const

LocInfo getLocInfo() const

static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)

static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)

bool isUpperBitsInLoc() const

static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)

unsigned getExtraInfo() const

int64_t getLocMemOffset() const

unsigned getValNo() const

static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)

void convertToMem(int64_t Offset)

This is an important class for using LLVM in a threaded context.

Wrapper class representing physical registers. Should be passed by value.

Wrapper class representing virtual and physical registers.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void swap(SmallVectorImpl &RHS)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

@ C

The default llvm calling convention, compatible with C.

This is an optimization pass for GlobalISel generic memory operations.

bool CCCustomFn(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)

CCCustomFn - This function assigns a location for Val, possibly updating all args to reflect changes ...

constexpr T MinAlign(U A, V B)

A and B are either alignments or offsets.

bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)

CCAssignFn - This function assigns a location for Val, updating State to reflect the change.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

This struct is a compact representation of a valid (non-zero power of two) alignment.

Describes a register that needs to be forwarded from the prologue to a musttail call.

ForwardedRegister(Register VReg, MCPhysReg PReg, MVT VT)