LLVM: lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

21#include

22

23using namespace llvm;

25

29 assert(Args.size() >= 1 && "Needs a minimum of one expression.");

30 assert(Kind != AGVK_None && "Cannot construct AMDGPUMCExpr of kind none.");

31

32

33

34

35

36

37 RawArgs = static_cast<const MCExpr **>(

39 std::uninitialized_copy(Args.begin(), Args.end(), RawArgs);

41}

42

43AMDGPUMCExpr::~AMDGPUMCExpr() { Ctx.deallocate(RawArgs); }

44

48 return new (Ctx) AMDGPUMCExpr(Kind, Args, Ctx);

49}

50

52 assert(Index < Args.size() && "Indexing out of bounds AMDGPUMCExpr sub-expr");

53 return Args[Index];

54}

55

57 switch (Kind) {

58 default:

61 OS << "or(";

62 break;

64 OS << "max(";

65 break;

67 OS << "extrasgprs(";

68 break;

70 OS << "totalnumvgprs(";

71 break;

73 OS << "alignto(";

74 break;

76 OS << "occupancy(";

77 break;

78 }

79 for (const auto *It = Args.begin(); It != Args.end(); ++It) {

80 (*It)->print(OS, MAI, false);

81 if ((It + 1) != Args.end())

82 OS << ", ";

83 }

84 OS << ')';

85}

86

88 switch (Kind) {

89 default:

92 return std::max(Arg1, Arg2);

94 return Arg1 | Arg2;

95 }

96}

97

98bool AMDGPUMCExpr::evaluateExtraSGPRs(MCValue &Res, const MCAssembler *Asm,

100 auto TryGetMCExprValue = [&](const MCExpr *Arg, uint64_t &ConstantValue) {

103 return false;

104

106 return true;

107 };

108

110 "AMDGPUMCExpr Argument count incorrect for ExtraSGPRs");

112 uint64_t VCCUsed = 0, FlatScrUsed = 0, XNACKUsed = 0;

113

114 bool Success = TryGetMCExprValue(Args[2], XNACKUsed);

115

116 assert(Success && "Arguments 3 for ExtraSGPRs should be a known constant");

117 if (Success || !TryGetMCExprValue(Args[0], VCCUsed) ||

118 !TryGetMCExprValue(Args[1], FlatScrUsed))

119 return false;

120

122 STI, (bool)VCCUsed, (bool)FlatScrUsed, (bool)XNACKUsed);

124 return true;

125}

126

127bool AMDGPUMCExpr::evaluateTotalNumVGPR(MCValue &Res, const MCAssembler *Asm,

129 auto TryGetMCExprValue = [&](const MCExpr *Arg, uint64_t &ConstantValue) {

132 return false;

133

135 return true;

136 };

138 "AMDGPUMCExpr Argument count incorrect for TotalNumVGPRs");

140 uint64_t NumAGPR = 0, NumVGPR = 0;

141

143

144 if (!TryGetMCExprValue(Args[0], NumAGPR) ||

145 !TryGetMCExprValue(Args[1], NumVGPR))

146 return false;

147

148 uint64_t TotalNum = Has90AInsts && NumAGPR ? alignTo(NumVGPR, 4) + NumAGPR

149 : std::max(NumVGPR, NumAGPR);

151 return true;

152}

153

154bool AMDGPUMCExpr::evaluateAlignTo(MCValue &Res, const MCAssembler *Asm,

156 auto TryGetMCExprValue = [&](const MCExpr *Arg, uint64_t &ConstantValue) {

159 return false;

160

162 return true;

163 };

164

166 "AMDGPUMCExpr Argument count incorrect for AlignTo");

168 if (!TryGetMCExprValue(Args[0], Value) || !TryGetMCExprValue(Args[1], Align))

169 return false;

170

172 return true;

173}

174

175bool AMDGPUMCExpr::evaluateOccupancy(MCValue &Res, const MCAssembler *Asm,

177 auto TryGetMCExprValue = [&](const MCExpr *Arg, uint64_t &ConstantValue) {

180 return false;

181

183 return true;

184 };

186 "AMDGPUMCExpr Argument count incorrect for Occupancy");

187 uint64_t InitOccupancy, MaxWaves, Granule, TargetTotalNumVGPRs, Generation,

189

191 Success &= TryGetMCExprValue(Args[0], MaxWaves);

192 Success &= TryGetMCExprValue(Args[1], Granule);

193 Success &= TryGetMCExprValue(Args[2], TargetTotalNumVGPRs);

194 Success &= TryGetMCExprValue(Args[3], Generation);

195 Success &= TryGetMCExprValue(Args[4], InitOccupancy);

196

197 assert(Success && "Arguments 1 to 5 for Occupancy should be known constants");

198

199 if (Success || !TryGetMCExprValue(Args[5], NumSGPRs) ||

200 !TryGetMCExprValue(Args[6], NumVGPRs))

201 return false;

202

203 unsigned Occupancy = InitOccupancy;

204 if (NumSGPRs)

205 Occupancy = std::min(

207 NumSGPRs, MaxWaves,

209 if (NumVGPRs)

210 Occupancy = std::min(Occupancy,

212 NumVGPRs, Granule, MaxWaves, TargetTotalNumVGPRs));

213

215 return true;

216}

217

221 std::optional<int64_t> Total;

222 switch (Kind) {

223 default:

224 break;

226 return evaluateExtraSGPRs(Res, Asm, Fixup);

228 return evaluateAlignTo(Res, Asm, Fixup);

230 return evaluateTotalNumVGPR(Res, Asm, Fixup);

232 return evaluateOccupancy(Res, Asm, Fixup);

233 }

234

235 for (const MCExpr *Arg : Args) {

238 return false;

239

240 if (Total.has_value())

243 }

244

246 return true;

247}

248

250 for (const MCExpr *Arg : Args)

252}

253

255 for (const MCExpr *Arg : Args) {

258 }

259 return nullptr;

260}

261

262

263

264

265

267 const MCExpr *FlatScrUsed,

268 bool XNACKUsed,

270

273 Ctx);

274}

275

277 const MCExpr *NumVGPR,

280}

281

282

283

284

285

286

288 const MCExpr *NumSGPRs,

289 const MCExpr *NumVGPRs,

296

297 auto CreateExpr = [&Ctx](unsigned Value) {

299 };

300

302 {CreateExpr(MaxWaves), CreateExpr(Granule),

303 CreateExpr(TargetTotalNumVGPRs), CreateExpr(Generation),

304 CreateExpr(InitOcc), NumSGPRs, NumVGPRs},

305 Ctx);

306}

307

310 if (E->isSymbolUsedInExpression(Sym))

311 return true;

312 }

313 return false;

314}

315

317 static constexpr unsigned BitWidth = 64;

320 if (CompareResult) {

323 }

324

325 KnownBits UnknownBool(1);

327}

328

331 unsigned Depth = 0);

332

334 unsigned Depth) {

335 static constexpr unsigned BitWidth = 64;

336 const MCBinaryExpr *BExpr = cast(Expr);

339

344

346 default:

348 return;

351 return;

353 KBM[Expr] = LHSKnown & RHSKnown;

354 return;

357 return;

359 std::optional CompareRes = KnownBits::eq(LHSKnown, RHSKnown);

361 return;

362 }

364 std::optional CompareRes = KnownBits::ne(LHSKnown, RHSKnown);

366 return;

367 }

369 std::optional CompareRes = KnownBits::sgt(LHSKnown, RHSKnown);

371 return;

372 }

374 std::optional CompareRes = KnownBits::sge(LHSKnown, RHSKnown);

376 return;

377 }

379 std::optional CompareRes;

381 std::optional LHSBool =

383 std::optional RHSBool =

385 if (LHSBool && RHSBool)

386 CompareRes = *LHSBool && *RHSBool;

388 return;

389 }

392 KnownBits Bits = LHSKnown | RHSKnown;

393 std::optional CompareRes =

396 return;

397 }

399 std::optional CompareRes = KnownBits::slt(LHSKnown, RHSKnown);

401 return;

402 }

404 std::optional CompareRes = KnownBits::sle(LHSKnown, RHSKnown);

406 return;

407 }

410 return;

413 return;

415 KBM[Expr] = LHSKnown | RHSKnown;

416 return;

419 return;

422 return;

425 return;

428 return;

430 KBM[Expr] = LHSKnown ^ RHSKnown;

431 return;

432 }

433}

434

436 unsigned Depth) {

437 static constexpr unsigned BitWidth = 64;

438 const MCUnaryExpr *UExpr = cast(Expr);

441

443 default:

445 return;

448 KBM[Expr] = KB;

449 return;

450 }

454 KBM[Expr] = KB ^ AllOnes;

455 return;

456 }

459 KBM[Expr] = KB;

460 return;

461 }

462 }

463}

464

466 unsigned Depth) {

467 static constexpr unsigned BitWidth = 64;

468 const AMDGPUMCExpr *AGVK = cast(Expr);

469

470 switch (AGVK->getKind()) {

471 default:

473 return;

479 KB |= KBM[Arg];

480 }

481 KBM[Expr] = KB;

482 return;

483 }

490 }

491 KBM[Expr] = KB;

492 return;

493 }

498 int64_t Val;

502 return;

503 }

505 return;

506 }

507 }

508}

509

511 unsigned Depth) {

512 static constexpr unsigned BitWidth = 64;

513

514 int64_t Val;

515 if (Expr->evaluateAsAbsolute(Val)) {

518 return;

519 }

520

521 if (Depth == 16) {

523 return;

524 }

525

526 switch (Expr->getKind()) {

529 return;

530 }

532 const MCConstantExpr *CE = cast(Expr);

533 APInt APValue(BitWidth, CE->getValue(), true);

535 return;

536 }

538 const MCSymbolRefExpr *RExpr = cast(Expr);

540 if (Sym.isVariable()) {

542 return;

543 }

544

545

546

547 const MCExpr *SymVal = Sym.getVariableValue(false);

549

550

551

552 KBM[Expr] = KnownBits(KBM[SymVal]);

553 return;

554 }

557 return;

558 }

561 return;

562 }

563 }

564}

565

568 if (!KBM.count(Expr))

569 return Expr;

570

571 auto ValueCheckKnownBits = [](KnownBits &KB, unsigned Value) -> bool {

573 return false;

574

576 };

577

579 return Expr;

580

581

582

583

586 APInt ConstVal = KBM[Expr].getConstant();

588 }

589

590 int64_t EvalValue;

591 if (Expr->evaluateAsAbsolute(EvalValue))

593 }

594

595 switch (Expr->getKind()) {

596 default:

597 return Expr;

599 const MCBinaryExpr *BExpr = cast(Expr);

602

604 default:

605 return Expr;

607 if (ValueCheckKnownBits(KBM[RHS], 0))

609 break;

610 }

613 if (ValueCheckKnownBits(KBM[LHS], 0))

615 if (ValueCheckKnownBits(KBM[RHS], 0))

617 break;

618 }

620 if (ValueCheckKnownBits(KBM[LHS], 1))

622 if (ValueCheckKnownBits(KBM[RHS], 1))

624 break;

625 }

629 if (ValueCheckKnownBits(KBM[RHS], 0))

631 if (ValueCheckKnownBits(KBM[LHS], 0))

633 break;

634 }

636 if (ValueCheckKnownBits(KBM[LHS], 0) || ValueCheckKnownBits(KBM[RHS], 0))

638 break;

639 }

640 }

643 if (NewLHS != LHS || NewRHS != RHS)

646 return Expr;

647 }

649 const MCUnaryExpr *UExpr = cast(Expr);

652 if (SubExpr != NewSubExpr)

655 return Expr;

656 }

658 const AMDGPUMCExpr *AGVK = cast(Expr);

660 bool Changed = false;

664 Changed |= Arg != NewArg;

665 }

667 }

668 }

669 return Expr;

670}

671

677

679}

680

683 int64_t Val;

684 if (Expr->evaluateAsAbsolute(Val)) {

685 OS << Val;

686 return;

687 }

688

690}

static bool isConstant(const MachineInstr &MI)

static void targetOpKnownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM, unsigned Depth)

static void unaryOpKnownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM, unsigned Depth)

static KnownBits fromOptionalToKnownBits(std::optional< bool > CompareResult)

static void binaryOpKnownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM, unsigned Depth)

static const MCExpr * tryFoldHelper(const MCExpr *Expr, KnownBitsMap &KBM, MCContext &Ctx)

static void knownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM, unsigned Depth=0)

AMD GCN specific subclass of TargetSubtarget.

PowerPC TLS Dynamic Call Fixup

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

AMDGPU target specific MCExpr operations.

ArrayRef< const MCExpr * > getArgs() const

MCFragment * findAssociatedFragment() const override

void visitUsedExpr(MCStreamer &Streamer) const override

static const AMDGPUMCExpr * createOccupancy(unsigned InitOcc, const MCExpr *NumSGPRs, const MCExpr *NumVGPRs, const GCNSubtarget &STM, MCContext &Ctx)

Mimics GCNSubtarget::computeOccupancy for MCExpr.

static const AMDGPUMCExpr * createTotalNumVGPR(const MCExpr *NumAGPR, const MCExpr *NumVGPR, MCContext &Ctx)

static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)

static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)

Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...

bool isSymbolUsedInExpression(const MCSymbol *Sym) const override

const MCExpr * getSubExpr(size_t Index) const

bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const override

void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override

VariantKind getKind() const

Class for arbitrary precision integers.

int64_t getSExtValue() const

Get sign extended value.

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

size_type count(const_arg_type_t< KeyT > Val) const

Return 1 if the specified key is in the map, 0 otherwise.

Generation getGeneration() const

This class is intended to be used as a base class for asm properties and features specific to the tar...

Binary assembler expressions.

const MCExpr * getLHS() const

Get the left-hand side expression of the binary operator.

const MCExpr * getRHS() const

Get the right-hand side expression of the binary operator.

Opcode getOpcode() const

Get the kind of this binary expression.

static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

@ AShr

Arithmetic shift right.

@ LShr

Logical shift right.

@ GTE

Signed greater than or equal comparison (result is either 0 or some target-specific non-zero value).

@ GT

Signed greater than comparison (result is either 0 or some target-specific non-zero value)

@ Xor

Bitwise exclusive or.

@ LT

Signed less than comparison (result is either 0 or some target-specific non-zero value).

@ LTE

Signed less than or equal comparison (result is either 0 or some target-specific non-zero value).

@ NE

Inequality comparison.

static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

void * allocate(unsigned Size, unsigned Align=8)

void deallocate(void *Ptr)

const MCSubtargetInfo * getSubtargetInfo() const

Base class for the full range of assembler expressions which are needed for parsing.

bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm, const SectionAddrMap &Addrs) const

Try to evaluate the expression to an absolute value.

@ Unary

Unary expressions.

@ Constant

Constant expressions.

@ SymbolRef

References to labels and assigned expressions.

@ Target

Target specific expression.

@ Binary

Binary expressions.

bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const

Try to evaluate the expression to a relocatable value, i.e.

void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const

MCFragment * findAssociatedFragment() const

Find the "associated section" for this expression, which is currently defined as the absolute section...

Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...

Streaming machine code generation interface.

void visitUsedExpr(const MCExpr &Expr)

Generic base class for all target subtargets.

Represent a reference to a symbol from inside an expression.

const MCSymbol & getSymbol() const

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

Unary assembler expressions.

Opcode getOpcode() const

Get the kind of this unary expression.

static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())

const MCExpr * getSubExpr() const

Get the child of this unary expression.

This represents an "assembler immediate".

int64_t getConstant() const

static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)

bool isAbsolute() const

Is this an absolute (as opposed to relocatable) value.

void push_back(const T &Elt)

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

LLVM Value Representation.

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char NumVGPRs[]

Key for Kernel::CodeProps::Metadata::mNumVGPRs.

constexpr char NumSGPRs[]

Key for Kernel::CodeProps::Metadata::mNumSGPRs.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

unsigned getTotalNumVGPRs(const MCSubtargetInfo *STI)

unsigned getMaxWavesPerEU(const MCSubtargetInfo *STI)

unsigned getNumExtraSGPRs(const MCSubtargetInfo *STI, bool VCCUsed, bool FlatScrUsed, bool XNACKUsed)

unsigned getNumWavesPerEUWithNumVGPRs(const MCSubtargetInfo *STI, unsigned NumVGPRs)

unsigned getOccupancyWithNumSGPRs(unsigned SGPRs, unsigned MaxWaves, AMDGPUSubtarget::Generation Gen)

unsigned getVGPRAllocGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)

void printAMDGPUMCExpr(const MCExpr *Expr, raw_ostream &OS, const MCAsmInfo *MAI)

bool isGFX90A(const MCSubtargetInfo &STI)

const MCExpr * foldAMDGPUMCExpr(const MCExpr *Expr, MCContext &Ctx)

This is an optimization pass for GlobalISel generic memory operations.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

constexpr unsigned BitWidth

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

static KnownBits makeConstant(const APInt &C)

Create known bits from a known constant.

static std::optional< bool > eq(const KnownBits &LHS, const KnownBits &RHS)

Determine if these known bits always give the same ICMP_EQ result.

void makeNonNegative()

Make this value non-negative.

static KnownBits ashr(const KnownBits &LHS, const KnownBits &RHS, bool ShAmtNonZero=false, bool Exact=false)

Compute known bits for ashr(LHS, RHS).

static std::optional< bool > ne(const KnownBits &LHS, const KnownBits &RHS)

Determine if these known bits always give the same ICMP_NE result.

void makeNegative()

Make this value negative.

static std::optional< bool > sge(const KnownBits &LHS, const KnownBits &RHS)

Determine if these known bits always give the same ICMP_SGE result.

static KnownBits umax(const KnownBits &LHS, const KnownBits &RHS)

Compute known bits for umax(LHS, RHS).

KnownBits zext(unsigned BitWidth) const

Return known bits for a zero extension of the value we're tracking.

bool isConstant() const

Returns true if we know the value of all bits.

static KnownBits lshr(const KnownBits &LHS, const KnownBits &RHS, bool ShAmtNonZero=false, bool Exact=false)

Compute known bits for lshr(LHS, RHS).

static KnownBits add(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false)

Compute knownbits resulting from addition of LHS and RHS.

static KnownBits srem(const KnownBits &LHS, const KnownBits &RHS)

Compute known bits for srem(LHS, RHS).

static std::optional< bool > slt(const KnownBits &LHS, const KnownBits &RHS)

Determine if these known bits always give the same ICMP_SLT result.

static KnownBits sdiv(const KnownBits &LHS, const KnownBits &RHS, bool Exact=false)

Compute known bits for sdiv(LHS, RHS).

static KnownBits sub(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false)

Compute knownbits resulting from subtraction of LHS and RHS.

static KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)

Compute known bits resulting from multiplying LHS and RHS.

static std::optional< bool > sle(const KnownBits &LHS, const KnownBits &RHS)

Determine if these known bits always give the same ICMP_SLE result.

static std::optional< bool > sgt(const KnownBits &LHS, const KnownBits &RHS)

Determine if these known bits always give the same ICMP_SGT result.

static KnownBits shl(const KnownBits &LHS, const KnownBits &RHS, bool NUW=false, bool NSW=false, bool ShAmtNonZero=false)

Compute known bits for shl(LHS, RHS).

const APInt & getConstant() const

Returns the value when all bits have a known value.