LLVM 23.0.0git
AMDGPUMCExpr.cpp
Go to the documentation of this file.
1//===- AMDGPUMCExpr.cpp - AMDGPU specific MC expression classes -----------===//
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#include "AMDGPUMCExpr.h"
11#include "llvm/MC/MCAsmInfo.h"
12#include "llvm/MC/MCAssembler.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCStreamer.h"
15#include "llvm/MC/MCSymbol.h"
16#include "llvm/MC/MCValue.h"
19#include <functional>
20#include <optional>
21
22using namespace llvm;
23using namespace llvm::AMDGPU;
24
25AMDGPUMCExpr::AMDGPUMCExpr(VariantKind Kind, ArrayRef<const MCExpr *> Args,
26 MCContext &Ctx)
27 : Kind(Kind), Ctx(Ctx) {
28 assert(Args.size() >= 1 && "Needs a minimum of one expression.");
29 assert(Kind != AGVK_None && "Cannot construct AMDGPUMCExpr of kind none.");
30
31 // Allocating the variadic arguments through the same allocation mechanism
32 // that the object itself is allocated with so they end up in the same memory.
33 //
34 // Will result in an asan failure if allocated on the heap through standard
35 // allocation (e.g., through SmallVector's grow).
36 RawArgs = static_cast<const MCExpr **>(
37 Ctx.allocate(sizeof(const MCExpr *) * Args.size()));
38 llvm::uninitialized_copy(Args, RawArgs);
39 this->Args = ArrayRef<const MCExpr *>(RawArgs, Args.size());
40}
41
42AMDGPUMCExpr::~AMDGPUMCExpr() { Ctx.deallocate(RawArgs); }
43
44const AMDGPUMCExpr *AMDGPUMCExpr::create(VariantKind Kind,
46 MCContext &Ctx) {
47 return new (Ctx) AMDGPUMCExpr(Kind, Args, Ctx);
48}
49
50const MCExpr *AMDGPUMCExpr::getSubExpr(size_t Index) const {
51 assert(Index < Args.size() && "Indexing out of bounds AMDGPUMCExpr sub-expr");
52 return Args[Index];
53}
54
55void AMDGPUMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
56 switch (Kind) {
57 default:
58 llvm_unreachable("Unknown AMDGPUMCExpr kind.");
59 case AGVK_Or:
60 OS << "or(";
61 break;
62 case AGVK_Max:
63 OS << "max(";
64 break;
65 case AGVK_ExtraSGPRs:
66 OS << "extrasgprs(";
67 break;
69 OS << "totalnumvgprs(";
70 break;
71 case AGVK_AlignTo:
72 OS << "alignto(";
73 break;
74 case AGVK_Occupancy:
75 OS << "occupancy(";
76 break;
77 case AGVK_Lit:
78 OS << "lit(";
79 break;
80 case AGVK_Lit64:
81 OS << "lit64(";
82 break;
83 }
84 for (const auto *It = Args.begin(); It != Args.end(); ++It) {
85 MAI->printExpr(OS, **It);
86 if ((It + 1) != Args.end())
87 OS << ", ";
88 }
89 OS << ')';
90}
91
92static int64_t op(AMDGPUMCExpr::VariantKind Kind, int64_t Arg1, int64_t Arg2) {
93 switch (Kind) {
94 default:
95 llvm_unreachable("Unknown AMDGPUMCExpr kind.");
97 return std::max(Arg1, Arg2);
99 return Arg1 | Arg2;
100 }
101}
102
103static bool
105 std::initializer_list<std::reference_wrapper<uint64_t>> Vals) {
106 return llvm::all_of(llvm::zip_equal(Exprs, Vals), [&](const auto &Pair) {
107 auto [Expr, ValRef] = Pair;
108 uint64_t &Val = ValRef.get();
109 MCValue MCVal;
110 if (!Expr->evaluateAsRelocatable(MCVal, Asm) || !MCVal.isAbsolute())
111 return false;
112 Val = MCVal.getConstant();
113 return true;
114 });
115}
116
117bool AMDGPUMCExpr::evaluateExtraSGPRs(MCValue &Res,
118 const MCAssembler *Asm) const {
119 const MCSubtargetInfo *STI = Ctx.getSubtargetInfo();
120 uint64_t VCCUsed = 0, FlatScrUsed = 0, XNACKUsed = 0;
121
122 if (!evaluateMCExprs(Args, Asm, {VCCUsed, FlatScrUsed, XNACKUsed}))
123 return false;
124
125 uint64_t ExtraSGPRs = IsaInfo::getNumExtraSGPRs(
126 STI, (bool)VCCUsed, (bool)FlatScrUsed, (bool)XNACKUsed);
127 Res = MCValue::get(ExtraSGPRs);
128 return true;
129}
130
131bool AMDGPUMCExpr::evaluateTotalNumVGPR(MCValue &Res,
132 const MCAssembler *Asm) const {
133 const MCSubtargetInfo *STI = Ctx.getSubtargetInfo();
134 uint64_t NumAGPR = 0, NumVGPR = 0;
135
136 bool Has90AInsts = AMDGPU::isGFX90A(*STI);
137
138 if (!evaluateMCExprs(Args, Asm, {NumAGPR, NumVGPR}))
139 return false;
140
141 uint64_t TotalNum = Has90AInsts && NumAGPR ? alignTo(NumVGPR, 4) + NumAGPR
142 : std::max(NumVGPR, NumAGPR);
143 Res = MCValue::get(TotalNum);
144 return true;
145}
146
147bool AMDGPUMCExpr::evaluateAlignTo(MCValue &Res, const MCAssembler *Asm) const {
148 uint64_t Value = 0, Align = 0;
149 if (!evaluateMCExprs(Args, Asm, {Value, Align}))
150 return false;
151
152 Res = MCValue::get(alignTo(Value, Align));
153 return true;
154}
155
156bool AMDGPUMCExpr::evaluateOccupancy(MCValue &Res,
157 const MCAssembler *Asm) const {
158 uint64_t InitOccupancy, MaxWaves, Granule, TargetTotalNumVGPRs, Generation,
160
162 Args.slice(0, 5), Asm,
163 {MaxWaves, Granule, TargetTotalNumVGPRs, Generation, InitOccupancy});
164
165 assert(Success && "Arguments 1 to 5 for Occupancy should be known constants");
166
167 if (!Success || !evaluateMCExprs(Args.slice(5, 2), Asm, {NumSGPRs, NumVGPRs}))
168 return false;
169
170 unsigned Occupancy = InitOccupancy;
171 if (NumSGPRs)
172 Occupancy = std::min(
174 NumSGPRs, MaxWaves,
175 static_cast<AMDGPUSubtarget::Generation>(Generation)));
176 if (NumVGPRs)
177 Occupancy = std::min(Occupancy,
179 NumVGPRs, Granule, MaxWaves, TargetTotalNumVGPRs));
180
181 Res = MCValue::get(Occupancy);
182 return true;
183}
184
186 const MCExpr *E) {
187 switch (E->getKind()) {
188 case MCExpr::Constant:
189 return false;
190 case MCExpr::Unary:
192 Sym, static_cast<const MCUnaryExpr *>(E)->getSubExpr());
193 case MCExpr::Binary: {
194 const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(E);
195 return isSymbolUsedInExpression(Sym, BE->getLHS()) ||
197 }
198 case MCExpr::SymbolRef: {
199 const MCSymbol &S = static_cast<const MCSymbolRefExpr *>(E)->getSymbol();
200 if (S.isVariable())
202 return &S == Sym;
203 }
205 case MCExpr::Target: {
206 auto *TE = static_cast<const AMDGPUMCExpr *>(E);
207 for (const MCExpr *E : TE->getArgs())
208 if (isSymbolUsedInExpression(Sym, E))
209 return true;
210 return false;
211 }
212 }
213 llvm_unreachable("Unknown expr kind!");
214}
215
217 const MCAssembler *Asm) const {
218 std::optional<int64_t> Total;
219 switch (Kind) {
220 default:
221 break;
222 case AGVK_ExtraSGPRs:
223 return evaluateExtraSGPRs(Res, Asm);
224 case AGVK_AlignTo:
225 return evaluateAlignTo(Res, Asm);
227 return evaluateTotalNumVGPR(Res, Asm);
228 case AGVK_Occupancy:
229 return evaluateOccupancy(Res, Asm);
230 case AGVK_Lit:
231 case AGVK_Lit64:
232 return Args[0]->evaluateAsRelocatable(Res, Asm);
233 }
234
235 for (const MCExpr *Arg : Args) {
236 MCValue ArgRes;
237 if (!Arg->evaluateAsRelocatable(ArgRes, Asm) || !ArgRes.isAbsolute())
238 return false;
239
240 if (!Total.has_value())
241 Total = ArgRes.getConstant();
242 Total = op(Kind, *Total, ArgRes.getConstant());
243 }
244
245 Res = MCValue::get(*Total);
246 return true;
247}
248
250 for (const MCExpr *Arg : Args)
251 Streamer.visitUsedExpr(*Arg);
252}
253
255 for (const MCExpr *Arg : Args) {
256 if (Arg->findAssociatedFragment())
257 return Arg->findAssociatedFragment();
258 }
259 return nullptr;
260}
261
262/// Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed
263/// are unresolvable but needed for further MCExprs). Derived from
264/// implementation of IsaInfo::getNumExtraSGPRs in AMDGPUBaseInfo.cpp.
265///
266const AMDGPUMCExpr *AMDGPUMCExpr::createExtraSGPRs(const MCExpr *VCCUsed,
267 const MCExpr *FlatScrUsed,
268 bool XNACKUsed,
269 MCContext &Ctx) {
270
271 return create(AGVK_ExtraSGPRs,
272 {VCCUsed, FlatScrUsed, MCConstantExpr::create(XNACKUsed, Ctx)},
273 Ctx);
274}
275
276const AMDGPUMCExpr *AMDGPUMCExpr::createTotalNumVGPR(const MCExpr *NumAGPR,
277 const MCExpr *NumVGPR,
278 MCContext &Ctx) {
279 return create(AGVK_TotalNumVGPRs, {NumAGPR, NumVGPR}, Ctx);
280}
281
282const AMDGPUMCExpr *AMDGPUMCExpr::createLit(LitModifier Lit, int64_t Value,
283 MCContext &Ctx) {
287 {MCConstantExpr::create(Value, Ctx, /*PrintInHex=*/true)}, Ctx);
288}
289
290static KnownBits fromOptionalToKnownBits(std::optional<bool> CompareResult) {
291 static constexpr unsigned BitWidth = 64;
292 const APInt True(BitWidth, 1);
293 const APInt False(BitWidth, 0);
294 if (CompareResult) {
295 return *CompareResult ? KnownBits::makeConstant(True)
297 }
298
299 KnownBits UnknownBool(/*BitWidth=*/1);
300 return UnknownBool.zext(BitWidth);
301}
302
304static void knownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM,
305 unsigned Depth = 0);
306
307static void binaryOpKnownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM,
308 unsigned Depth) {
309 static constexpr unsigned BitWidth = 64;
310 const MCBinaryExpr *BExpr = cast<MCBinaryExpr>(Expr);
311 const MCExpr *LHS = BExpr->getLHS();
312 const MCExpr *RHS = BExpr->getRHS();
313
314 knownBitsMapHelper(LHS, KBM, Depth + 1);
315 knownBitsMapHelper(RHS, KBM, Depth + 1);
316 KnownBits LHSKnown = KBM[LHS];
317 KnownBits RHSKnown = KBM[RHS];
318
319 switch (BExpr->getOpcode()) {
320 default:
321 KBM[Expr] = KnownBits(BitWidth);
322 return;
324 KBM[Expr] = KnownBits::add(LHSKnown, RHSKnown);
325 return;
327 KBM[Expr] = LHSKnown & RHSKnown;
328 return;
330 KBM[Expr] = KnownBits::sdiv(LHSKnown, RHSKnown);
331 return;
333 std::optional<bool> CompareRes = KnownBits::eq(LHSKnown, RHSKnown);
334 KBM[Expr] = fromOptionalToKnownBits(CompareRes);
335 return;
336 }
338 std::optional<bool> CompareRes = KnownBits::ne(LHSKnown, RHSKnown);
339 KBM[Expr] = fromOptionalToKnownBits(CompareRes);
340 return;
341 }
343 std::optional<bool> CompareRes = KnownBits::sgt(LHSKnown, RHSKnown);
344 KBM[Expr] = fromOptionalToKnownBits(CompareRes);
345 return;
346 }
348 std::optional<bool> CompareRes = KnownBits::sge(LHSKnown, RHSKnown);
349 KBM[Expr] = fromOptionalToKnownBits(CompareRes);
350 return;
351 }
353 std::optional<bool> CompareRes;
354 const APInt False(BitWidth, 0);
355 std::optional<bool> LHSBool =
356 KnownBits::ne(LHSKnown, KnownBits::makeConstant(False));
357 std::optional<bool> RHSBool =
358 KnownBits::ne(RHSKnown, KnownBits::makeConstant(False));
359 if (LHSBool && RHSBool)
360 CompareRes = *LHSBool && *RHSBool;
361 KBM[Expr] = fromOptionalToKnownBits(CompareRes);
362 return;
363 }
365 const APInt False(BitWidth, 0);
366 KnownBits Bits = LHSKnown | RHSKnown;
367 std::optional<bool> CompareRes =
369 KBM[Expr] = fromOptionalToKnownBits(CompareRes);
370 return;
371 }
373 std::optional<bool> CompareRes = KnownBits::slt(LHSKnown, RHSKnown);
374 KBM[Expr] = fromOptionalToKnownBits(CompareRes);
375 return;
376 }
378 std::optional<bool> CompareRes = KnownBits::sle(LHSKnown, RHSKnown);
379 KBM[Expr] = fromOptionalToKnownBits(CompareRes);
380 return;
381 }
383 KBM[Expr] = KnownBits::srem(LHSKnown, RHSKnown);
384 return;
386 KBM[Expr] = KnownBits::mul(LHSKnown, RHSKnown);
387 return;
389 KBM[Expr] = LHSKnown | RHSKnown;
390 return;
392 KBM[Expr] = KnownBits::shl(LHSKnown, RHSKnown);
393 return;
395 KBM[Expr] = KnownBits::ashr(LHSKnown, RHSKnown);
396 return;
398 KBM[Expr] = KnownBits::lshr(LHSKnown, RHSKnown);
399 return;
401 KBM[Expr] = KnownBits::sub(LHSKnown, RHSKnown);
402 return;
404 KBM[Expr] = LHSKnown ^ RHSKnown;
405 return;
406 }
407}
408
409static void unaryOpKnownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM,
410 unsigned Depth) {
411 static constexpr unsigned BitWidth = 64;
412 const MCUnaryExpr *UExpr = cast<MCUnaryExpr>(Expr);
413 knownBitsMapHelper(UExpr->getSubExpr(), KBM, Depth + 1);
414 KnownBits KB = KBM[UExpr->getSubExpr()];
415
416 switch (UExpr->getOpcode()) {
417 default:
418 KBM[Expr] = KnownBits(BitWidth);
419 return;
421 KB.makeNegative();
422 KBM[Expr] = std::move(KB);
423 return;
424 }
427 AllOnes.setAllOnes();
428 KBM[Expr] = KB ^ AllOnes;
429 return;
430 }
432 KB.makeNonNegative();
433 KBM[Expr] = std::move(KB);
434 return;
435 }
436 }
437}
438
439static void targetOpKnownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM,
440 unsigned Depth) {
441 static constexpr unsigned BitWidth = 64;
442 const AMDGPUMCExpr *AGVK = cast<AMDGPUMCExpr>(Expr);
443
444 switch (AGVK->getKind()) {
445 default:
446 KBM[Expr] = KnownBits(BitWidth);
447 return;
449 knownBitsMapHelper(AGVK->getSubExpr(0), KBM, Depth + 1);
450 KnownBits KB = KBM[AGVK->getSubExpr(0)];
451 for (const MCExpr *Arg : AGVK->getArgs()) {
452 knownBitsMapHelper(Arg, KBM, Depth + 1);
453 KB |= KBM[Arg];
454 }
455 KBM[Expr] = std::move(KB);
456 return;
457 }
459 knownBitsMapHelper(AGVK->getSubExpr(0), KBM, Depth + 1);
460 KnownBits KB = KBM[AGVK->getSubExpr(0)];
461 for (const MCExpr *Arg : AGVK->getArgs()) {
462 knownBitsMapHelper(Arg, KBM, Depth + 1);
463 KB = KnownBits::umax(KB, KBM[Arg]);
464 }
465 KBM[Expr] = std::move(KB);
466 return;
467 }
474 int64_t Val;
475 if (AGVK->evaluateAsAbsolute(Val)) {
476 APInt APValue(BitWidth, Val);
477 KBM[Expr] = KnownBits::makeConstant(APValue);
478 return;
479 }
480 KBM[Expr] = KnownBits(BitWidth);
481 return;
482 }
483 }
484}
485
486static void knownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM,
487 unsigned Depth) {
488 static constexpr unsigned BitWidth = 64;
489
490 int64_t Val;
491 if (Expr->evaluateAsAbsolute(Val)) {
492 APInt APValue(BitWidth, Val, /*isSigned=*/true);
493 KBM[Expr] = KnownBits::makeConstant(APValue);
494 return;
495 }
496
497 if (Depth == 16) {
498 KBM[Expr] = KnownBits(BitWidth);
499 return;
500 }
501
502 switch (Expr->getKind()) {
505 return;
506 }
508 const MCConstantExpr *CE = cast<MCConstantExpr>(Expr);
509 APInt APValue(BitWidth, CE->getValue(), /*isSigned=*/true);
510 KBM[Expr] = KnownBits::makeConstant(APValue);
511 return;
512 }
514 const MCSymbolRefExpr *RExpr = cast<MCSymbolRefExpr>(Expr);
515 const MCSymbol &Sym = RExpr->getSymbol();
516 if (!Sym.isVariable()) {
517 KBM[Expr] = KnownBits(BitWidth);
518 return;
519 }
520
521 // Variable value retrieval is not for actual use but only for knownbits
522 // analysis.
523 const MCExpr *SymVal = Sym.getVariableValue();
524 knownBitsMapHelper(SymVal, KBM, Depth + 1);
525
526 // Explicitly copy-construct so that there exists a local KnownBits in case
527 // KBM[SymVal] gets invalidated after a potential growth through KBM[Expr].
528 KBM[Expr] = KnownBits(KBM[SymVal]);
529 return;
530 }
533 return;
534 }
537 return;
539 llvm_unreachable("unused by this backend");
540 }
541 }
542}
543
544static const MCExpr *tryFoldHelper(const MCExpr *Expr, KnownBitsMap &KBM,
545 MCContext &Ctx) {
546 if (!KBM.count(Expr))
547 return Expr;
548
549 auto ValueCheckKnownBits = [](KnownBits &KB, unsigned Value) -> bool {
550 if (!KB.isConstant())
551 return false;
552
553 return Value == KB.getConstant();
554 };
555
556 if (Expr->getKind() == MCExpr::ExprKind::Constant)
557 return Expr;
558
559 // Resolving unary operations to constants may make the value more ambiguous.
560 // For example, `~62` becomes `-63`; however, to me it's more ambiguous if a
561 // bit mask value is represented through a negative number.
562 if (Expr->getKind() != MCExpr::ExprKind::Unary) {
563 if (KBM[Expr].isConstant()) {
564 APInt ConstVal = KBM[Expr].getConstant();
565 return MCConstantExpr::create(ConstVal.getSExtValue(), Ctx);
566 }
567
568 int64_t EvalValue;
569 if (Expr->evaluateAsAbsolute(EvalValue))
570 return MCConstantExpr::create(EvalValue, Ctx);
571 }
572
573 switch (Expr->getKind()) {
574 default:
575 return Expr;
577 const MCBinaryExpr *BExpr = cast<MCBinaryExpr>(Expr);
578 const MCExpr *LHS = BExpr->getLHS();
579 const MCExpr *RHS = BExpr->getRHS();
580
581 switch (BExpr->getOpcode()) {
582 default:
583 return Expr;
585 if (ValueCheckKnownBits(KBM[RHS], 0))
586 return tryFoldHelper(LHS, KBM, Ctx);
587 break;
588 }
591 if (ValueCheckKnownBits(KBM[LHS], 0))
592 return tryFoldHelper(RHS, KBM, Ctx);
593 if (ValueCheckKnownBits(KBM[RHS], 0))
594 return tryFoldHelper(LHS, KBM, Ctx);
595 break;
596 }
598 if (ValueCheckKnownBits(KBM[LHS], 1))
599 return tryFoldHelper(RHS, KBM, Ctx);
600 if (ValueCheckKnownBits(KBM[RHS], 1))
601 return tryFoldHelper(LHS, KBM, Ctx);
602 break;
603 }
607 if (ValueCheckKnownBits(KBM[RHS], 0))
608 return tryFoldHelper(LHS, KBM, Ctx);
609 if (ValueCheckKnownBits(KBM[LHS], 0))
610 return MCConstantExpr::create(0, Ctx);
611 break;
612 }
614 if (ValueCheckKnownBits(KBM[LHS], 0) || ValueCheckKnownBits(KBM[RHS], 0))
615 return MCConstantExpr::create(0, Ctx);
616 break;
617 }
618 }
619 const MCExpr *NewLHS = tryFoldHelper(LHS, KBM, Ctx);
620 const MCExpr *NewRHS = tryFoldHelper(RHS, KBM, Ctx);
621 if (NewLHS != LHS || NewRHS != RHS)
622 return MCBinaryExpr::create(BExpr->getOpcode(), NewLHS, NewRHS, Ctx,
623 BExpr->getLoc());
624 return Expr;
625 }
627 const MCUnaryExpr *UExpr = cast<MCUnaryExpr>(Expr);
628 const MCExpr *SubExpr = UExpr->getSubExpr();
629 const MCExpr *NewSubExpr = tryFoldHelper(SubExpr, KBM, Ctx);
630 if (SubExpr != NewSubExpr)
631 return MCUnaryExpr::create(UExpr->getOpcode(), NewSubExpr, Ctx,
632 UExpr->getLoc());
633 return Expr;
634 }
636 const AMDGPUMCExpr *AGVK = cast<AMDGPUMCExpr>(Expr);
638 bool Changed = false;
639 for (const MCExpr *Arg : AGVK->getArgs()) {
640 const MCExpr *NewArg = tryFoldHelper(Arg, KBM, Ctx);
641 NewArgs.push_back(NewArg);
642 Changed |= Arg != NewArg;
643 }
644 return Changed ? AMDGPUMCExpr::create(AGVK->getKind(), NewArgs, Ctx) : Expr;
645 }
646 }
647 return Expr;
648}
649
651 MCContext &Ctx) {
652 KnownBitsMap KBM;
653 knownBitsMapHelper(Expr, KBM);
654 const MCExpr *NewExpr = tryFoldHelper(Expr, KBM, Ctx);
655
656 return Expr != NewExpr ? NewExpr : Expr;
657}
658
660 const MCAsmInfo *MAI) {
661 int64_t Val;
662 if (Expr->evaluateAsAbsolute(Val)) {
663 OS << Val;
664 return;
665 }
666
667 MAI->printExpr(OS, *Expr);
668}
669
670bool AMDGPU::isLitExpr(const MCExpr *Expr) {
671 const auto *E = dyn_cast<AMDGPUMCExpr>(Expr);
672 return E && (E->getKind() == AMDGPUMCExpr::AGVK_Lit ||
673 E->getKind() == AMDGPUMCExpr::AGVK_Lit64);
674}
675
676int64_t AMDGPU::getLitValue(const MCExpr *Expr) {
677 assert(isLitExpr(Expr));
678 return cast<MCConstantExpr>(cast<AMDGPUMCExpr>(Expr)->getArgs()[0])
679 ->getValue();
680}
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)
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)
static bool evaluateMCExprs(ArrayRef< const MCExpr * > Exprs, const MCAssembler *Asm, std::initializer_list< std::reference_wrapper< uint64_t > > Vals)
DenseMap< const MCExpr *, KnownBits > KnownBitsMap
#define op(i)
Value * RHS
Value * LHS
AMDGPU target specific MCExpr operations.
ArrayRef< const MCExpr * > getArgs() const
MCFragment * findAssociatedFragment() const override
void visitUsedExpr(MCStreamer &Streamer) const override
static const AMDGPUMCExpr * createTotalNumVGPR(const MCExpr *NumAGPR, const MCExpr *NumVGPR, MCContext &Ctx)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm) const override
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...
const MCExpr * getSubExpr(size_t Index) const
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override
VariantKind getKind() const
static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *E)
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1585
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:174
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:64
void printExpr(raw_ostream &, const MCExpr &) const
Binary assembler expressions.
Definition MCExpr.h:299
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition MCExpr.h:446
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition MCExpr.h:449
Opcode getOpcode() const
Get the kind of this binary expression.
Definition MCExpr.h:443
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:201
@ Div
Signed division.
Definition MCExpr.h:304
@ Shl
Shift left.
Definition MCExpr.h:321
@ AShr
Arithmetic shift right.
Definition MCExpr.h:322
@ LShr
Logical shift right.
Definition MCExpr.h:323
@ GTE
Signed greater than or equal comparison (result is either 0 or some target-specific non-zero value).
Definition MCExpr.h:308
@ EQ
Equality comparison.
Definition MCExpr.h:305
@ Sub
Subtraction.
Definition MCExpr.h:324
@ Mul
Multiplication.
Definition MCExpr.h:317
@ GT
Signed greater than comparison (result is either 0 or some target-specific non-zero value)
Definition MCExpr.h:306
@ Mod
Signed remainder.
Definition MCExpr.h:316
@ And
Bitwise and.
Definition MCExpr.h:303
@ Or
Bitwise or.
Definition MCExpr.h:319
@ Xor
Bitwise exclusive or.
Definition MCExpr.h:325
@ LAnd
Logical and.
Definition MCExpr.h:310
@ LOr
Logical or.
Definition MCExpr.h:311
@ LT
Signed less than comparison (result is either 0 or some target-specific non-zero value).
Definition MCExpr.h:312
@ Add
Addition.
Definition MCExpr.h:302
@ LTE
Signed less than or equal comparison (result is either 0 or some target-specific non-zero value).
Definition MCExpr.h:314
@ NE
Inequality comparison.
Definition MCExpr.h:318
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
@ Unary
Unary expressions.
Definition MCExpr.h:44
@ Constant
Constant expressions.
Definition MCExpr.h:42
@ SymbolRef
References to labels and assigned expressions.
Definition MCExpr.h:43
@ Target
Target specific expression.
Definition MCExpr.h:46
@ Specifier
Expression with a relocation specifier.
Definition MCExpr.h:45
@ Binary
Binary expressions.
Definition MCExpr.h:41
LLVM_ABI bool evaluateAsAbsolute(int64_t &Res) const
Try to evaluate the expression to an absolute value.
Definition MCExpr.cpp:238
ExprKind getKind() const
Definition MCExpr.h:85
SMLoc getLoc() const
Definition MCExpr.h:86
Streaming machine code generation interface.
Definition MCStreamer.h:222
void visitUsedExpr(const MCExpr &Expr)
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
const MCSymbol & getSymbol() const
Definition MCExpr.h:227
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition MCSymbol.h:267
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
Definition MCSymbol.h:270
Unary assembler expressions.
Definition MCExpr.h:243
Opcode getOpcode() const
Get the kind of this unary expression.
Definition MCExpr.h:286
static LLVM_ABI const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:207
@ Minus
Unary minus.
Definition MCExpr.h:247
@ Plus
Unary plus.
Definition MCExpr.h:249
@ Not
Bitwise negation.
Definition MCExpr.h:248
const MCExpr * getSubExpr() const
Get the child of this unary expression.
Definition MCExpr.h:289
static MCValue get(const MCSymbol *SymA, const MCSymbol *SymB=nullptr, int64_t Val=0, uint32_t Specifier=0)
Definition MCValue.h:56
int64_t getConstant() const
Definition MCValue.h:44
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
Definition MCValue.h:54
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.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Changed
#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)
void printAMDGPUMCExpr(const MCExpr *Expr, raw_ostream &OS, const MCAsmInfo *MAI)
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
const MCExpr * foldAMDGPUMCExpr(const MCExpr *Expr, MCContext &Ctx)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1738
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:840
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto uninitialized_copy(R &&Src, IterTy Dst)
Definition STLExtras.h:2110
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
@ Success
The lock was released successfully.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
Definition KnownBits.h:315
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.
Definition KnownBits.h:125
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.
Definition KnownBits.h:120
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.
Definition KnownBits.h:176
bool isConstant() const
Returns true if we know the value of all bits.
Definition KnownBits.h:54
static KnownBits add(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false, bool SelfAdd=false)
Compute knownbits resulting from addition of LHS and RHS.
Definition KnownBits.h:361
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 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.
Definition KnownBits.h:376
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.
Definition KnownBits.h:58