1//===- AMDGPUMCExpr.h - AMDGPU specific MC expression classes ---*- C++ -*-===//
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#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
10#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
11
12#include "llvm/ADT/ArrayRef.h"
13#include "llvm/MC/MCExpr.h"
14
15namespace llvm {
16
17class Function;
18
19enum class LitModifier { None, Lit, Lit64 };
20
21/// AMDGPU target specific MCExpr operations.
22///
23/// Takes in a minimum of 1 argument to be used with an operation. The supported
24/// operations are:
25/// - (bitwise) or
26/// - max
27///
28/// \note If the 'or'/'max' operations are provided only a single argument, the
29/// operation will act as a no-op and simply resolve as the provided argument.
30///
31class AMDGPUMCExpr : public MCTargetExpr {
32public:
33 enum VariantKind {
34 AGVK_None,
35 AGVK_Or,
36 AGVK_Max,
37 AGVK_ExtraSGPRs,
38 AGVK_TotalNumVGPRs,
39 AGVK_AlignTo,
40 AGVK_Occupancy,
41 AGVK_Lit,
42 AGVK_Lit64,
43 };
44
45 // Relocation specifiers.
46 enum Specifier {
47 S_None,
48 S_GOTPCREL, // symbol@gotpcrel
49 S_GOTPCREL32_LO, // symbol@gotpcrel32@lo
50 S_GOTPCREL32_HI, // symbol@gotpcrel32@hi
51 S_REL32_LO, // symbol@rel32@lo
52 S_REL32_HI, // symbol@rel32@hi
53 S_REL64, // symbol@rel64
54 S_ABS32_LO, // symbol@abs32@lo
55 S_ABS32_HI, // symbol@abs32@hi
56 S_ABS64, // symbol@abs64
57 };
58
59private:
60 VariantKind Kind;
61 MCContext &Ctx;
62 const MCExpr **RawArgs;
63 ArrayRef<const MCExpr *> Args;
64
65 AMDGPUMCExpr(VariantKind Kind, ArrayRef<const MCExpr *> Args, MCContext &Ctx);
66 ~AMDGPUMCExpr() override;
67
68 bool evaluateExtraSGPRs(MCValue &Res, const MCAssembler *Asm) const;
69 bool evaluateTotalNumVGPR(MCValue &Res, const MCAssembler *Asm) const;
70 bool evaluateAlignTo(MCValue &Res, const MCAssembler *Asm) const;
71 bool evaluateOccupancy(MCValue &Res, const MCAssembler *Asm) const;
72
73public:
74 static const AMDGPUMCExpr *
75 create(VariantKind Kind, ArrayRef<const MCExpr *> Args, MCContext &Ctx);
76
77 static const AMDGPUMCExpr *createOr(ArrayRef<const MCExpr *> Args,
78 MCContext &Ctx) {
79 return create(Kind: VariantKind::AGVK_Or, Args, Ctx);
80 }
81
82 static const AMDGPUMCExpr *createMax(ArrayRef<const MCExpr *> Args,
83 MCContext &Ctx) {
84 return create(Kind: VariantKind::AGVK_Max, Args, Ctx);
85 }
86
87 static const AMDGPUMCExpr *createExtraSGPRs(const MCExpr *VCCUsed,
88 const MCExpr *FlatScrUsed,
89 bool XNACKUsed, MCContext &Ctx);
90
91 static const AMDGPUMCExpr *createTotalNumVGPR(const MCExpr *NumAGPR,
92 const MCExpr *NumVGPR,
93 MCContext &Ctx);
94
95 static const AMDGPUMCExpr *
96 createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx) {
97 return create(Kind: VariantKind::AGVK_AlignTo, Args: {Value, Align}, Ctx);
98 }
99
100 static const AMDGPUMCExpr *createLit(LitModifier Lit, int64_t Value,
101 MCContext &Ctx);
102
103 ArrayRef<const MCExpr *> getArgs() const { return Args; }
104 VariantKind getKind() const { return Kind; }
105 const MCExpr *getSubExpr(size_t Index) const;
106
107 void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
108 bool evaluateAsRelocatableImpl(MCValue &Res,
109 const MCAssembler *Asm) const override;
110 void visitUsedExpr(MCStreamer &Streamer) const override;
111 MCFragment *findAssociatedFragment() const override;
112
113 static bool classof(const MCExpr *E) {
114 return E->getKind() == MCExpr::Target;
115 }
116 static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *E);
117};
118
119namespace AMDGPU {
120// Tries to leverage KnownBits for MCExprs to reduce and limit any composed
121// MCExprs printing. E.g., for an expression such as
122// ((unevaluatable_sym | 1) & 1) won't evaluate due to unevaluatable_sym and
123// would verbosely print the full expression; however, KnownBits should deduce
124// the value to be 1. Particularly useful for AMDGPU metadata MCExprs.
125void printAMDGPUMCExpr(const MCExpr *Expr, raw_ostream &OS,
126 const MCAsmInfo *MAI);
127
128const MCExpr *foldAMDGPUMCExpr(const MCExpr *Expr, MCContext &Ctx);
129
130static inline AMDGPUMCExpr::Specifier getSpecifier(const MCSymbolRefExpr *SRE) {
131 return AMDGPUMCExpr::Specifier(SRE->getKind());
132}
133
134LLVM_READONLY bool isLitExpr(const MCExpr *Expr);
135
136LLVM_READONLY int64_t getLitValue(const MCExpr *Expr);
137
138} // end namespace AMDGPU
139} // end namespace llvm
140
141#endif // LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
142