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

1

2

3

4

5

6

7

8

19#include

20

21using namespace llvm;

23

26 : Kind(Kind), Ctx(Ctx) {

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

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

29

30

31

32

33

34

35 RawArgs = static_cast<const MCExpr **>(

36 Ctx.allocate(sizeof(const MCExpr *) * Args.size()));

39}

40

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

42

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

47}

48

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

51 return Args[Index];

52}

53

55 switch (Kind) {

56 default:

59 OS << "or(";

60 break;

62 OS << "max(";

63 break;

65 OS << "extrasgprs(";

66 break;

68 OS << "totalnumvgprs(";

69 break;

71 OS << "alignto(";

72 break;

74 OS << "occupancy(";

75 break;

77 OS << "lit(";

78 break;

80 OS << "lit64(";

81 break;

82 }

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

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

86 OS << ", ";

87 }

88 OS << ')';

89}

90

92 switch (Kind) {

93 default:

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

98 return Arg1 | Arg2;

99 }

100}

101

102bool AMDGPUMCExpr::evaluateExtraSGPRs(MCValue &Res,

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

105 MCValue MCVal;

107 return false;

108

110 return true;

111 };

112

113 assert(Args.size() == 3 &&

114 "AMDGPUMCExpr Argument count incorrect for ExtraSGPRs");

115 const MCSubtargetInfo *STI = Ctx.getSubtargetInfo();

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

117

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

119

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

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

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

123 return false;

124

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

128 return true;

129}

130

131bool AMDGPUMCExpr::evaluateTotalNumVGPR(MCValue &Res,

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

134 MCValue MCVal;

136 return false;

137

139 return true;

140 };

141 assert(Args.size() == 2 &&

142 "AMDGPUMCExpr Argument count incorrect for TotalNumVGPRs");

143 const MCSubtargetInfo *STI = Ctx.getSubtargetInfo();

144 uint64_t NumAGPR = 0, NumVGPR = 0;

145

147

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

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

150 return false;

151

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

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

155 return true;

156}

157

158bool AMDGPUMCExpr::evaluateAlignTo(MCValue &Res, const MCAssembler *Asm) const {

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

160 MCValue MCVal;

162 return false;

163

165 return true;

166 };

167

168 assert(Args.size() == 2 &&

169 "AMDGPUMCExpr Argument count incorrect for AlignTo");

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

172 return false;

173

175 return true;

176}

177

178bool AMDGPUMCExpr::evaluateOccupancy(MCValue &Res,

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

181 MCValue MCVal;

183 return false;

184

186 return true;

187 };

188 assert(Args.size() == 7 &&

189 "AMDGPUMCExpr Argument count incorrect for Occupancy");

190 uint64_t InitOccupancy, MaxWaves, Granule, TargetTotalNumVGPRs, Generation,

192

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

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

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

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

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

199

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

201

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

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

204 return false;

205

206 unsigned Occupancy = InitOccupancy;

207 if (NumSGPRs)

208 Occupancy = std::min(

210 NumSGPRs, MaxWaves,

212 if (NumVGPRs)

213 Occupancy = std::min(Occupancy,

215 NumVGPRs, Granule, MaxWaves, TargetTotalNumVGPRs));

216

218 return true;

219}

220

223 switch (E->getKind()) {

225 return false;

233 }

238 return &S == Sym;

239 }

242 auto *TE = static_cast<const AMDGPUMCExpr *>(E);

243 for (const MCExpr *E : TE->getArgs())

245 return true;

246 return false;

247 }

248 }

250}

251

254 std::optional<int64_t> Total;

255 switch (Kind) {

256 default:

257 break;

259 return evaluateExtraSGPRs(Res, Asm);

261 return evaluateAlignTo(Res, Asm);

263 return evaluateTotalNumVGPR(Res, Asm);

265 return evaluateOccupancy(Res, Asm);

268 return Args[0]->evaluateAsRelocatable(Res, Asm);

269 }

270

271 for (const MCExpr *Arg : Args) {

274 return false;

275

276 if (Total.has_value())

279 }

280

282 return true;

283}

284

286 for (const MCExpr *Arg : Args)

288}

289

291 for (const MCExpr *Arg : Args) {

294 }

295 return nullptr;

296}

297

298

299

300

301

303 const MCExpr *FlatScrUsed,

304 bool XNACKUsed,

306

309 Ctx);

310}

311

313 const MCExpr *NumVGPR,

316}

317

325

327 static constexpr unsigned BitWidth = 64;

330 if (CompareResult) {

333 }

334

335 KnownBits UnknownBool(1);

337}

338

341 unsigned Depth = 0);

342

344 unsigned Depth) {

345 static constexpr unsigned BitWidth = 64;

349

354

356 default:

358 return;

361 return;

363 KBM[Expr] = LHSKnown & RHSKnown;

364 return;

367 return;

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

371 return;

372 }

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

376 return;

377 }

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

381 return;

382 }

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

386 return;

387 }

389 std::optional CompareRes;

391 std::optional LHSBool =

393 std::optional RHSBool =

395 if (LHSBool && RHSBool)

396 CompareRes = *LHSBool && *RHSBool;

398 return;

399 }

402 KnownBits Bits = LHSKnown | RHSKnown;

403 std::optional CompareRes =

406 return;

407 }

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

411 return;

412 }

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

416 return;

417 }

420 return;

423 return;

425 KBM[Expr] = LHSKnown | RHSKnown;

426 return;

429 return;

432 return;

435 return;

438 return;

440 KBM[Expr] = LHSKnown ^ RHSKnown;

441 return;

442 }

443}

444

446 unsigned Depth) {

447 static constexpr unsigned BitWidth = 64;

451

453 default:

455 return;

458 KBM[Expr] = KB;

459 return;

460 }

464 KBM[Expr] = KB ^ AllOnes;

465 return;

466 }

469 KBM[Expr] = KB;

470 return;

471 }

472 }

473}

474

476 unsigned Depth) {

477 static constexpr unsigned BitWidth = 64;

479

480 switch (AGVK->getKind()) {

481 default:

483 return;

489 KB |= KBM[Arg];

490 }

491 KBM[Expr] = KB;

492 return;

493 }

500 }

501 KBM[Expr] = KB;

502 return;

503 }

510 int64_t Val;

514 return;

515 }

517 return;

518 }

519 }

520}

521

523 unsigned Depth) {

524 static constexpr unsigned BitWidth = 64;

525

526 int64_t Val;

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

530 return;

531 }

532

533 if (Depth == 16) {

535 return;

536 }

537

538 switch (Expr->getKind()) {

541 return;

542 }

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

547 return;

548 }

554 return;

555 }

556

557

558

561

562

563

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

565 return;

566 }

569 return;

570 }

573 return;

576 }

577 }

578}

579

582 if (!KBM.count(Expr))

583 return Expr;

584

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

587 return false;

588

590 };

591

593 return Expr;

594

595

596

597

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

602 }

603

604 int64_t EvalValue;

605 if (Expr->evaluateAsAbsolute(EvalValue))

607 }

608

609 switch (Expr->getKind()) {

610 default:

611 return Expr;

616

618 default:

619 return Expr;

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

623 break;

624 }

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

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

631 break;

632 }

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

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

638 break;

639 }

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

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

647 break;

648 }

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

652 break;

653 }

654 }

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

660 return Expr;

661 }

666 if (SubExpr != NewSubExpr)

669 return Expr;

670 }

678 Changed |= Arg != NewArg;

679 }

681 }

682 }

683 return Expr;

684}

685

694

697 int64_t Val;

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

699 OS << Val;

700 return;

701 }

702

704}

705

711

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static bool isConstant(const MachineInstr &MI)

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

Definition AMDGPUMCExpr.cpp:475

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

Definition AMDGPUMCExpr.cpp:445

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

Definition AMDGPUMCExpr.cpp:326

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

Definition AMDGPUMCExpr.cpp:343

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

Definition AMDGPUMCExpr.cpp:580

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

Definition AMDGPUMCExpr.cpp:522

DenseMap< const MCExpr *, KnownBits > KnownBitsMap

Definition AMDGPUMCExpr.cpp:339

AMDGPU target specific MCExpr operations.

ArrayRef< const MCExpr * > getArgs() const

MCFragment * findAssociatedFragment() const override

Definition AMDGPUMCExpr.cpp:290

void visitUsedExpr(MCStreamer &Streamer) const override

Definition AMDGPUMCExpr.cpp:285

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

Definition AMDGPUMCExpr.cpp:312

static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)

Definition AMDGPUMCExpr.cpp:318

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

Definition AMDGPUMCExpr.cpp:43

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

Definition AMDGPUMCExpr.cpp:252

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...

Definition AMDGPUMCExpr.cpp:302

const MCExpr * getSubExpr(size_t Index) const

Definition AMDGPUMCExpr.cpp:49

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

Definition AMDGPUMCExpr.cpp:54

VariantKind getKind() const

static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *E)

Definition AMDGPUMCExpr.cpp:221

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.

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

void printExpr(raw_ostream &, const MCExpr &) const

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 LLVM_ABI 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 LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

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

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

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

MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData=0)

@ Unary

Unary expressions.

@ Constant

Constant expressions.

@ SymbolRef

References to labels and assigned expressions.

@ Target

Target specific expression.

@ Specifier

Expression with a relocation specifier.

@ Binary

Binary expressions.

LLVM_ABI bool evaluateAsAbsolute(int64_t &Res) const

Try to evaluate the expression to an absolute value.

LLVM_ABI MCFragment * findAssociatedFragment() const

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

Streaming machine code generation interface.

void visitUsedExpr(const MCExpr &Expr)

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 ...

bool isVariable() const

isVariable - Check if this is a variable symbol.

const MCExpr * getVariableValue() const

Get the expression of the variable symbol.

Unary assembler expressions.

Opcode getOpcode() const

Get the kind of this unary expression.

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

const MCExpr * getSubExpr() const

Get the child of this unary expression.

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

int64_t getConstant() const

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 Align[]

Key for Kernel::Arg::Metadata::mAlign.

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 getNumWavesPerEUWithNumVGPRs(const MCSubtargetInfo *STI, unsigned NumVGPRs, unsigned DynamicVGPRBlockSize)

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

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

LLVM_READONLY bool isLitExpr(const MCExpr *Expr)

Definition AMDGPUMCExpr.cpp:706

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

Definition AMDGPUMCExpr.cpp:695

bool isGFX90A(const MCSubtargetInfo &STI)

LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)

Definition AMDGPUMCExpr.cpp:712

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

Definition AMDGPUMCExpr.cpp:686

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto uninitialized_copy(R &&Src, IterTy Dst)

@ Success

The lock was released successfully.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

ArrayRef(const T &OneElt) -> ArrayRef< T >

constexpr unsigned BitWidth

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

static KnownBits makeConstant(const APInt &C)

Create known bits from a known constant.

static LLVM_ABI 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 LLVM_ABI KnownBits ashr(const KnownBits &LHS, const KnownBits &RHS, bool ShAmtNonZero=false, bool Exact=false)

Compute known bits for ashr(LHS, RHS).

static LLVM_ABI 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 LLVM_ABI std::optional< bool > sge(const KnownBits &LHS, const KnownBits &RHS)

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

static LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI KnownBits srem(const KnownBits &LHS, const KnownBits &RHS)

Compute known bits for srem(LHS, RHS).

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

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

static LLVM_ABI 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 LLVM_ABI KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)

Compute known bits resulting from multiplying LHS and RHS.

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

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

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

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

static LLVM_ABI 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.