Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
213799 views
1
//===----------------------------------------------------------------------===//
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
// A helper class for emitting expressions and values as cir::ConstantOp
10
// and as initializers for global variables.
11
//
12
// Note: this is based on clang's LLVM IR codegen in ConstantEmitter.h, reusing
13
// this class interface makes it easier move forward with bringing CIR codegen
14
// to completion.
15
//
16
//===----------------------------------------------------------------------===//
17
18
#ifndef CLANG_LIB_CIR_CODEGEN_CIRGENCONSTANTEMITTER_H
19
#define CLANG_LIB_CIR_CODEGEN_CIRGENCONSTANTEMITTER_H
20
21
#include "CIRGenFunction.h"
22
#include "CIRGenModule.h"
23
24
namespace clang::CIRGen {
25
26
class ConstantEmitter {
27
public:
28
CIRGenModule &cgm;
29
const CIRGenFunction *cgf;
30
31
private:
32
bool abstract = false;
33
34
#ifndef NDEBUG
35
// Variables used for asserting state consistency.
36
37
/// Whether non-abstract components of the emitter have been initialized.
38
bool initializedNonAbstract = false;
39
40
/// Whether the emitter has been finalized.
41
bool finalized = false;
42
43
/// Whether the constant-emission failed.
44
bool failed = false;
45
#endif // NDEBUG
46
47
/// Whether we're in a constant context.
48
bool inConstantContext = false;
49
50
public:
51
/// Initialize this emission in the context of the given function.
52
/// Use this if the expression might contain contextual references like
53
/// block addresses or PredefinedExprs.
54
ConstantEmitter(CIRGenFunction &cgf) : cgm(cgf.cgm), cgf(&cgf) {}
55
56
ConstantEmitter(CIRGenModule &cgm, CIRGenFunction *cgf = nullptr)
57
: cgm(cgm), cgf(cgf) {}
58
59
ConstantEmitter(const ConstantEmitter &other) = delete;
60
ConstantEmitter &operator=(const ConstantEmitter &other) = delete;
61
62
~ConstantEmitter();
63
64
/// Try to emit the initializer of the given declaration as an abstract
65
/// constant. If this succeeds, the emission must be finalized.
66
mlir::Attribute tryEmitForInitializer(const VarDecl &d);
67
68
void finalize(cir::GlobalOp gv);
69
70
// All of the "abstract" emission methods below permit the emission to
71
// be immediately discarded without finalizing anything. Therefore, they
72
// must also promise not to do anything that will, in the future, require
73
// finalization:
74
//
75
// - using the CGF (if present) for anything other than establishing
76
// semantic context; for example, an expression with ignored
77
// side-effects must not be emitted as an abstract expression
78
//
79
// - doing anything that would not be safe to duplicate within an
80
// initializer or to propagate to another context; for example,
81
// side effects, or emitting an initialization that requires a
82
// reference to its current location.
83
mlir::Attribute emitForMemory(mlir::Attribute c, QualType t);
84
85
/// Try to emit the initializer of the given declaration as an abstract
86
/// constant.
87
mlir::Attribute tryEmitAbstractForInitializer(const VarDecl &d);
88
89
/// Emit the result of the given expression as an abstract constant,
90
/// asserting that it succeeded. This is only safe to do when the
91
/// expression is known to be a constant expression with either a fairly
92
/// simple type or a known simple form.
93
mlir::Attribute emitAbstract(SourceLocation loc, const APValue &value,
94
QualType t);
95
96
mlir::Attribute tryEmitConstantExpr(const ConstantExpr *ce);
97
98
// These are private helper routines of the constant emitter that
99
// can't actually be private because things are split out into helper
100
// functions and classes.
101
102
mlir::Attribute tryEmitPrivateForVarInit(const VarDecl &d);
103
104
mlir::Attribute tryEmitPrivate(const APValue &value, QualType destType);
105
mlir::Attribute tryEmitPrivateForMemory(const APValue &value, QualType t);
106
107
private:
108
#ifndef NDEBUG
109
void initializeNonAbstract() {
110
assert(!initializedNonAbstract);
111
initializedNonAbstract = true;
112
assert(!cir::MissingFeatures::addressSpace());
113
}
114
mlir::Attribute markIfFailed(mlir::Attribute init) {
115
if (!init)
116
failed = true;
117
return init;
118
}
119
#else
120
void initializeNonAbstract() {}
121
mlir::Attribute markIfFailed(mlir::Attribute init) { return init; }
122
#endif // NDEBUG
123
124
class AbstractStateRAII {
125
ConstantEmitter &emitter;
126
bool oldValue;
127
128
public:
129
AbstractStateRAII(ConstantEmitter &emitter, bool value)
130
: emitter(emitter), oldValue(emitter.abstract) {
131
emitter.abstract = value;
132
}
133
~AbstractStateRAII() { emitter.abstract = oldValue; }
134
};
135
};
136
137
} // namespace clang::CIRGen
138
139
#endif // CLANG_LIB_CIR_CODEGEN_CIRGENCONSTANTEMITTER_H
140
141