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