annotate clang/lib/CodeGen/ConstantEmitter.h @ 236:c4bab56944e8 llvm-original

LLVM 16
author kono
date Wed, 09 Nov 2022 17:45:10 +0900
parents 79ff65ed7e25
children 1f2b6ac9f198
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===--- ConstantEmitter.h - IR constant emission ---------------*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // A helper class for emitting expressions and values as llvm::Constants
anatofuz
parents:
diff changeset
10 // and as initializers for global variables.
anatofuz
parents:
diff changeset
11 //
anatofuz
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
anatofuz
parents:
diff changeset
15 #define LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 #include "CodeGenFunction.h"
anatofuz
parents:
diff changeset
18 #include "CodeGenModule.h"
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 namespace clang {
anatofuz
parents:
diff changeset
21 namespace CodeGen {
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23 class ConstantEmitter {
anatofuz
parents:
diff changeset
24 public:
anatofuz
parents:
diff changeset
25 CodeGenModule &CGM;
anatofuz
parents:
diff changeset
26 CodeGenFunction *const CGF;
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 private:
anatofuz
parents:
diff changeset
29 bool Abstract = false;
anatofuz
parents:
diff changeset
30
anatofuz
parents:
diff changeset
31 /// Whether non-abstract components of the emitter have been initialized.
anatofuz
parents:
diff changeset
32 bool InitializedNonAbstract = false;
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 /// Whether the emitter has been finalized.
anatofuz
parents:
diff changeset
35 bool Finalized = false;
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 /// Whether the constant-emission failed.
anatofuz
parents:
diff changeset
38 bool Failed = false;
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40 /// Whether we're in a constant context.
anatofuz
parents:
diff changeset
41 bool InConstantContext = false;
anatofuz
parents:
diff changeset
42
anatofuz
parents:
diff changeset
43 /// The AST address space where this (non-abstract) initializer is going.
anatofuz
parents:
diff changeset
44 /// Used for generating appropriate placeholders.
anatofuz
parents:
diff changeset
45 LangAS DestAddressSpace;
anatofuz
parents:
diff changeset
46
anatofuz
parents:
diff changeset
47 llvm::SmallVector<std::pair<llvm::Constant *, llvm::GlobalVariable*>, 4>
anatofuz
parents:
diff changeset
48 PlaceholderAddresses;
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 public:
anatofuz
parents:
diff changeset
51 ConstantEmitter(CodeGenModule &CGM, CodeGenFunction *CGF = nullptr)
anatofuz
parents:
diff changeset
52 : CGM(CGM), CGF(CGF) {}
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 /// Initialize this emission in the context of the given function.
anatofuz
parents:
diff changeset
55 /// Use this if the expression might contain contextual references like
anatofuz
parents:
diff changeset
56 /// block addresses or PredefinedExprs.
anatofuz
parents:
diff changeset
57 ConstantEmitter(CodeGenFunction &CGF)
anatofuz
parents:
diff changeset
58 : CGM(CGF.CGM), CGF(&CGF) {}
anatofuz
parents:
diff changeset
59
anatofuz
parents:
diff changeset
60 ConstantEmitter(const ConstantEmitter &other) = delete;
anatofuz
parents:
diff changeset
61 ConstantEmitter &operator=(const ConstantEmitter &other) = delete;
anatofuz
parents:
diff changeset
62
anatofuz
parents:
diff changeset
63 ~ConstantEmitter();
anatofuz
parents:
diff changeset
64
anatofuz
parents:
diff changeset
65 /// Is the current emission context abstract?
anatofuz
parents:
diff changeset
66 bool isAbstract() const {
anatofuz
parents:
diff changeset
67 return Abstract;
anatofuz
parents:
diff changeset
68 }
anatofuz
parents:
diff changeset
69
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
70 bool isInConstantContext() const { return InConstantContext; }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
71 void setInConstantContext(bool var) { InConstantContext = var; }
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
72
150
anatofuz
parents:
diff changeset
73 /// Try to emit the initiaizer of the given declaration as an abstract
anatofuz
parents:
diff changeset
74 /// constant. If this succeeds, the emission must be finalized.
anatofuz
parents:
diff changeset
75 llvm::Constant *tryEmitForInitializer(const VarDecl &D);
anatofuz
parents:
diff changeset
76 llvm::Constant *tryEmitForInitializer(const Expr *E, LangAS destAddrSpace,
anatofuz
parents:
diff changeset
77 QualType destType);
anatofuz
parents:
diff changeset
78 llvm::Constant *emitForInitializer(const APValue &value, LangAS destAddrSpace,
anatofuz
parents:
diff changeset
79 QualType destType);
anatofuz
parents:
diff changeset
80
anatofuz
parents:
diff changeset
81 void finalize(llvm::GlobalVariable *global);
anatofuz
parents:
diff changeset
82
anatofuz
parents:
diff changeset
83 // All of the "abstract" emission methods below permit the emission to
anatofuz
parents:
diff changeset
84 // be immediately discarded without finalizing anything. Therefore, they
anatofuz
parents:
diff changeset
85 // must also promise not to do anything that will, in the future, require
anatofuz
parents:
diff changeset
86 // finalization:
anatofuz
parents:
diff changeset
87 //
anatofuz
parents:
diff changeset
88 // - using the CGF (if present) for anything other than establishing
anatofuz
parents:
diff changeset
89 // semantic context; for example, an expression with ignored
anatofuz
parents:
diff changeset
90 // side-effects must not be emitted as an abstract expression
anatofuz
parents:
diff changeset
91 //
anatofuz
parents:
diff changeset
92 // - doing anything that would not be safe to duplicate within an
anatofuz
parents:
diff changeset
93 // initializer or to propagate to another context; for example,
anatofuz
parents:
diff changeset
94 // side effects, or emitting an initialization that requires a
anatofuz
parents:
diff changeset
95 // reference to its current location.
anatofuz
parents:
diff changeset
96
anatofuz
parents:
diff changeset
97 /// Try to emit the initializer of the given declaration as an abstract
anatofuz
parents:
diff changeset
98 /// constant.
anatofuz
parents:
diff changeset
99 llvm::Constant *tryEmitAbstractForInitializer(const VarDecl &D);
anatofuz
parents:
diff changeset
100
anatofuz
parents:
diff changeset
101 /// Emit the result of the given expression as an abstract constant,
anatofuz
parents:
diff changeset
102 /// asserting that it succeeded. This is only safe to do when the
anatofuz
parents:
diff changeset
103 /// expression is known to be a constant expression with either a fairly
anatofuz
parents:
diff changeset
104 /// simple type or a known simple form.
anatofuz
parents:
diff changeset
105 llvm::Constant *emitAbstract(const Expr *E, QualType T);
anatofuz
parents:
diff changeset
106 llvm::Constant *emitAbstract(SourceLocation loc, const APValue &value,
anatofuz
parents:
diff changeset
107 QualType T);
anatofuz
parents:
diff changeset
108
anatofuz
parents:
diff changeset
109 /// Try to emit the result of the given expression as an abstract constant.
anatofuz
parents:
diff changeset
110 llvm::Constant *tryEmitAbstract(const Expr *E, QualType T);
anatofuz
parents:
diff changeset
111 llvm::Constant *tryEmitAbstractForMemory(const Expr *E, QualType T);
anatofuz
parents:
diff changeset
112
anatofuz
parents:
diff changeset
113 llvm::Constant *tryEmitAbstract(const APValue &value, QualType T);
anatofuz
parents:
diff changeset
114 llvm::Constant *tryEmitAbstractForMemory(const APValue &value, QualType T);
anatofuz
parents:
diff changeset
115
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
116 llvm::Constant *tryEmitConstantExpr(const ConstantExpr *CE);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
117
150
anatofuz
parents:
diff changeset
118 llvm::Constant *emitNullForMemory(QualType T) {
anatofuz
parents:
diff changeset
119 return emitNullForMemory(CGM, T);
anatofuz
parents:
diff changeset
120 }
anatofuz
parents:
diff changeset
121 llvm::Constant *emitForMemory(llvm::Constant *C, QualType T) {
anatofuz
parents:
diff changeset
122 return emitForMemory(CGM, C, T);
anatofuz
parents:
diff changeset
123 }
anatofuz
parents:
diff changeset
124
anatofuz
parents:
diff changeset
125 static llvm::Constant *emitNullForMemory(CodeGenModule &CGM, QualType T);
anatofuz
parents:
diff changeset
126 static llvm::Constant *emitForMemory(CodeGenModule &CGM, llvm::Constant *C,
anatofuz
parents:
diff changeset
127 QualType T);
anatofuz
parents:
diff changeset
128
anatofuz
parents:
diff changeset
129 // These are private helper routines of the constant emitter that
anatofuz
parents:
diff changeset
130 // can't actually be private because things are split out into helper
anatofuz
parents:
diff changeset
131 // functions and classes.
anatofuz
parents:
diff changeset
132
anatofuz
parents:
diff changeset
133 llvm::Constant *tryEmitPrivateForVarInit(const VarDecl &D);
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 llvm::Constant *tryEmitPrivate(const Expr *E, QualType T);
anatofuz
parents:
diff changeset
136 llvm::Constant *tryEmitPrivateForMemory(const Expr *E, QualType T);
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 llvm::Constant *tryEmitPrivate(const APValue &value, QualType T);
anatofuz
parents:
diff changeset
139 llvm::Constant *tryEmitPrivateForMemory(const APValue &value, QualType T);
anatofuz
parents:
diff changeset
140
anatofuz
parents:
diff changeset
141 /// Get the address of the current location. This is a constant
anatofuz
parents:
diff changeset
142 /// that will resolve, after finalization, to the address of the
anatofuz
parents:
diff changeset
143 /// 'signal' value that is registered with the emitter later.
anatofuz
parents:
diff changeset
144 llvm::GlobalValue *getCurrentAddrPrivate();
anatofuz
parents:
diff changeset
145
anatofuz
parents:
diff changeset
146 /// Register a 'signal' value with the emitter to inform it where to
anatofuz
parents:
diff changeset
147 /// resolve a placeholder. The signal value must be unique in the
anatofuz
parents:
diff changeset
148 /// initializer; it might, for example, be the address of a global that
anatofuz
parents:
diff changeset
149 /// refers to the current-address value in its own initializer.
anatofuz
parents:
diff changeset
150 ///
anatofuz
parents:
diff changeset
151 /// Uses of the placeholder must be properly anchored before finalizing
anatofuz
parents:
diff changeset
152 /// the emitter, e.g. by being installed as the initializer of a global
anatofuz
parents:
diff changeset
153 /// variable. That is, it must be possible to replaceAllUsesWith
anatofuz
parents:
diff changeset
154 /// the placeholder with the proper address of the signal.
anatofuz
parents:
diff changeset
155 void registerCurrentAddrPrivate(llvm::Constant *signal,
anatofuz
parents:
diff changeset
156 llvm::GlobalValue *placeholder);
anatofuz
parents:
diff changeset
157
anatofuz
parents:
diff changeset
158 private:
anatofuz
parents:
diff changeset
159 void initializeNonAbstract(LangAS destAS) {
anatofuz
parents:
diff changeset
160 assert(!InitializedNonAbstract);
anatofuz
parents:
diff changeset
161 InitializedNonAbstract = true;
anatofuz
parents:
diff changeset
162 DestAddressSpace = destAS;
anatofuz
parents:
diff changeset
163 }
anatofuz
parents:
diff changeset
164 llvm::Constant *markIfFailed(llvm::Constant *init) {
anatofuz
parents:
diff changeset
165 if (!init)
anatofuz
parents:
diff changeset
166 Failed = true;
anatofuz
parents:
diff changeset
167 return init;
anatofuz
parents:
diff changeset
168 }
anatofuz
parents:
diff changeset
169
anatofuz
parents:
diff changeset
170 struct AbstractState {
anatofuz
parents:
diff changeset
171 bool OldValue;
anatofuz
parents:
diff changeset
172 size_t OldPlaceholdersSize;
anatofuz
parents:
diff changeset
173 };
anatofuz
parents:
diff changeset
174 AbstractState pushAbstract() {
anatofuz
parents:
diff changeset
175 AbstractState saved = { Abstract, PlaceholderAddresses.size() };
anatofuz
parents:
diff changeset
176 Abstract = true;
anatofuz
parents:
diff changeset
177 return saved;
anatofuz
parents:
diff changeset
178 }
anatofuz
parents:
diff changeset
179 llvm::Constant *validateAndPopAbstract(llvm::Constant *C, AbstractState save);
anatofuz
parents:
diff changeset
180 };
anatofuz
parents:
diff changeset
181
anatofuz
parents:
diff changeset
182 }
anatofuz
parents:
diff changeset
183 }
anatofuz
parents:
diff changeset
184
anatofuz
parents:
diff changeset
185 #endif