File: AMDGPUMCExpr.h

package info (click to toggle)
llvm-toolchain-21 1%3A21.1.6-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,245,028 kB
  • sloc: cpp: 7,619,726; ansic: 1,434,018; asm: 1,058,748; python: 252,740; f90: 94,671; objc: 70,685; lisp: 42,813; pascal: 18,401; sh: 8,601; ml: 5,111; perl: 4,720; makefile: 3,675; awk: 3,523; javascript: 2,409; xml: 892; fortran: 770
file content (134 lines) | stat: -rw-r--r-- 4,782 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//===- AMDGPUMCExpr.h - AMDGPU specific MC expression classes ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/MC/MCExpr.h"

namespace llvm {

class Function;
class GCNSubtarget;

/// AMDGPU target specific MCExpr operations.
///
/// Takes in a minimum of 1 argument to be used with an operation. The supported
/// operations are:
///   - (bitwise) or
///   - max
///
/// \note If the 'or'/'max' operations are provided only a single argument, the
/// operation will act as a no-op and simply resolve as the provided argument.
///
class AMDGPUMCExpr : public MCTargetExpr {
public:
  enum VariantKind {
    AGVK_None,
    AGVK_Or,
    AGVK_Max,
    AGVK_ExtraSGPRs,
    AGVK_TotalNumVGPRs,
    AGVK_AlignTo,
    AGVK_Occupancy
  };

  // Relocation specifiers.
  enum Specifier {
    S_None,
    S_GOTPCREL,      // symbol@gotpcrel
    S_GOTPCREL32_LO, // symbol@gotpcrel32@lo
    S_GOTPCREL32_HI, // symbol@gotpcrel32@hi
    S_REL32_LO,      // symbol@rel32@lo
    S_REL32_HI,      // symbol@rel32@hi
    S_REL64,         // symbol@rel64
    S_ABS32_LO,      // symbol@abs32@lo
    S_ABS32_HI,      // symbol@abs32@hi
  };

private:
  VariantKind Kind;
  MCContext &Ctx;
  const MCExpr **RawArgs;
  ArrayRef<const MCExpr *> Args;

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

  bool evaluateExtraSGPRs(MCValue &Res, const MCAssembler *Asm) const;
  bool evaluateTotalNumVGPR(MCValue &Res, const MCAssembler *Asm) const;
  bool evaluateAlignTo(MCValue &Res, const MCAssembler *Asm) const;
  bool evaluateOccupancy(MCValue &Res, const MCAssembler *Asm) const;

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

  static const AMDGPUMCExpr *createOr(ArrayRef<const MCExpr *> Args,
                                      MCContext &Ctx) {
    return create(VariantKind::AGVK_Or, Args, Ctx);
  }

  static const AMDGPUMCExpr *createMax(ArrayRef<const MCExpr *> Args,
                                       MCContext &Ctx) {
    return create(VariantKind::AGVK_Max, Args, Ctx);
  }

  static const AMDGPUMCExpr *createExtraSGPRs(const MCExpr *VCCUsed,
                                              const MCExpr *FlatScrUsed,
                                              bool XNACKUsed, MCContext &Ctx);

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

  static const AMDGPUMCExpr *
  createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx) {
    return create(VariantKind::AGVK_AlignTo, {Value, Align}, Ctx);
  }

  static const AMDGPUMCExpr *
  createOccupancy(unsigned InitOcc, const MCExpr *NumSGPRs,
                  const MCExpr *NumVGPRs, unsigned DynamicVGPRBlockSize,
                  const GCNSubtarget &STM, MCContext &Ctx);

  ArrayRef<const MCExpr *> getArgs() const { return Args; }
  VariantKind getKind() const { return Kind; }
  const MCExpr *getSubExpr(size_t Index) const;

  void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
  bool evaluateAsRelocatableImpl(MCValue &Res,
                                 const MCAssembler *Asm) const override;
  void visitUsedExpr(MCStreamer &Streamer) const override;
  MCFragment *findAssociatedFragment() const override;

  static bool classof(const MCExpr *E) {
    return E->getKind() == MCExpr::Target;
  }
  static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *E);
};

namespace AMDGPU {
// Tries to leverage KnownBits for MCExprs to reduce and limit any composed
// MCExprs printing. E.g., for an expression such as
// ((unevaluatable_sym | 1) & 1) won't evaluate due to unevaluatable_sym and
// would verbosely print the full expression; however, KnownBits should deduce
// the value to be 1. Particularly useful for AMDGPU metadata MCExprs.
void printAMDGPUMCExpr(const MCExpr *Expr, raw_ostream &OS,
                       const MCAsmInfo *MAI);

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

static inline AMDGPUMCExpr::Specifier getSpecifier(const MCSymbolRefExpr *SRE) {
  return AMDGPUMCExpr::Specifier(SRE->getKind());
}
} // end namespace AMDGPU
} // end namespace llvm

#endif // LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H