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