LLVM 23.0.0git
DXILValueEnumerator.h
Go to the documentation of this file.
1//===- DirectX/DXILWriter/ValueEnumerator.h - Number values -----*- 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// This class gives values and types Unique ID's.
10// Forked from lib/Bitcode/Writer
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_DXILWRITER_VALUEENUMERATOR_H
15#define LLVM_DXILWRITER_VALUEENUMERATOR_H
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/DenseMap.h"
20#include "llvm/IR/Attributes.h"
22#include <cassert>
23#include <cstdint>
24#include <utility>
25#include <vector>
26
27namespace llvm {
28
29class BasicBlock;
30class Comdat;
31class DIArgList;
32class Function;
33class Instruction;
34class LocalAsMetadata;
35class MDNode;
36class Metadata;
37class Module;
38class NamedMDNode;
39class raw_ostream;
40class Type;
41class Value;
43
44namespace dxil {
45
47
49public:
50 using TypeList = std::vector<Type *>;
51
52 // For each value, we remember its Value* and occurrence frequency.
53 using ValueList = std::vector<std::pair<const Value *, unsigned>>;
54
55 /// Attribute groups as encoded in bitcode are almost AttributeSets, but they
56 /// include the AttributeList index, so we have to track that in our map.
57 using IndexAndAttrSet = std::pair<unsigned, AttributeSet>;
58
60
61private:
62 using TypeMapType = DenseMap<Type *, unsigned>;
63 TypeMapType TypeMap;
64 TypeList Types;
65
66 using ValueMapType = DenseMap<const Value *, unsigned>;
67 ValueMapType ValueMap;
68 ValueList Values;
69
70 using ComdatSetType = UniqueVector<const Comdat *>;
71 ComdatSetType Comdats;
72
73 std::vector<const Metadata *> MDs;
74 std::vector<const Metadata *> FunctionMDs;
75
76 /// Index of information about a piece of metadata.
77 struct MDIndex {
78 unsigned F = 0; ///< The ID of the function for this metadata, if any.
79 unsigned ID = 0; ///< The implicit ID of this metadata in bitcode.
80
81 MDIndex() = default;
82 explicit MDIndex(unsigned F) : F(F) {}
83
84 /// Check if this has a function tag, and it's different from NewF.
85 bool hasDifferentFunction(unsigned NewF) const { return F && F != NewF; }
86
87 /// Fetch the MD this references out of the given metadata array.
88 const Metadata *get(ArrayRef<const Metadata *> MDs) const {
89 assert(ID && "Expected non-zero ID");
90 assert(ID <= MDs.size() && "Expected valid ID");
91 return MDs[ID - 1];
92 }
93 };
94
95 using MetadataMapType = DenseMap<const Metadata *, MDIndex>;
96 MetadataMapType MetadataMap;
97
98 /// Range of metadata IDs, as a half-open range.
99 struct MDRange {
100 unsigned First = 0;
101 unsigned Last = 0;
102
103 /// Number of strings in the prefix of the metadata range.
104 unsigned NumStrings = 0;
105
106 MDRange() = default;
107 explicit MDRange(unsigned First) : First(First) {}
108 };
109 SmallDenseMap<unsigned, MDRange, 1> FunctionMDInfo;
110
111 using AttributeGroupMapType = DenseMap<IndexAndAttrSet, unsigned>;
112 AttributeGroupMapType AttributeGroupMap;
113 std::vector<IndexAndAttrSet> AttributeGroups;
114
115 using AttributeListMapType = DenseMap<AttributeList, unsigned>;
116 AttributeListMapType AttributeListMap;
117 std::vector<AttributeList> AttributeLists;
118
119 /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
120 /// the "getGlobalBasicBlockID" method.
121 mutable DenseMap<const BasicBlock *, unsigned> GlobalBasicBlockIDs;
122
123 using InstructionMapType = DenseMap<const Instruction *, unsigned>;
124 InstructionMapType InstructionMap;
125 unsigned InstructionCount;
126
127 /// BasicBlocks - This contains all the basic blocks for the currently
128 /// incorporated function. Their reverse mapping is stored in ValueMap.
129 std::vector<const BasicBlock *> BasicBlocks;
130
131 /// When a function is incorporated, this is the size of the Values list
132 /// before incorporation.
133 unsigned NumModuleValues;
134
135 /// When a function is incorporated, this is the size of the Metadatas list
136 /// before incorporation.
137 unsigned NumModuleMDs = 0;
138 unsigned NumMDStrings = 0;
139
140 unsigned FirstFuncConstantID;
141 unsigned FirstInstID;
142
143 const DXILDebugInfoMap &DebugInfo;
144
145public:
146 ValueEnumerator(const Module &M, Type *PrefixType,
147 const DXILDebugInfoMap &DebugInfo);
150
151 void dump() const;
152 void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const;
153 void print(raw_ostream &OS, const MetadataMapType &Map,
154 const char *Name) const;
155
156 unsigned getValueID(const Value *V) const;
157
158 unsigned getMetadataID(const Metadata *MD) const {
159 auto ID = getMetadataOrNullID(MD);
160 assert(ID != 0 && "Metadata not in slotcalculator!");
161 return ID - 1;
162 }
163
164 unsigned getMetadataOrNullID(const Metadata *MD) const {
165 return MetadataMap.lookup(getDXILMetadata(MD)).ID;
166 }
167
168 unsigned numMDs() const { return MDs.size(); }
169
170 unsigned getTypeID(Type *T) const {
171 TypeMapType::const_iterator I = TypeMap.find(T);
172 assert(I != TypeMap.end() && "Type not in ValueEnumerator!");
173 return I->second - 1;
174 }
175
176 unsigned getInstructionID(const Instruction *I) const;
178
179 unsigned getAttributeListID(AttributeList PAL) const {
180 if (PAL.isEmpty())
181 return 0; // Null maps to zero.
182 AttributeListMapType::const_iterator I = AttributeListMap.find(PAL);
183 assert(I != AttributeListMap.end() && "Attribute not in ValueEnumerator!");
184 return I->second;
185 }
186
187 unsigned getAttributeGroupID(IndexAndAttrSet Group) const {
188 if (!Group.second.hasAttributes())
189 return 0; // Null maps to zero.
190 AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(Group);
191 assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!");
192 return I->second;
193 }
194
195 /// getFunctionConstantRange - Return the range of values that corresponds to
196 /// function-local constants.
197 void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
198 Start = FirstFuncConstantID;
199 End = FirstInstID;
200 }
201
202 const ValueList &getValues() const { return Values; }
203
204 /// Check whether the current block has any metadata to emit.
205 bool hasMDs() const { return NumModuleMDs < MDs.size(); }
206
207 /// Get the MDString metadata for this block.
209 return ArrayRef(MDs).slice(NumModuleMDs, NumMDStrings);
210 }
211
212 /// Get the non-MDString metadata for this block.
214 return ArrayRef(MDs).slice(NumModuleMDs).slice(NumMDStrings);
215 }
216
217 const TypeList &getTypes() const { return Types; }
218
219 const std::vector<const BasicBlock *> &getBasicBlocks() const {
220 return BasicBlocks;
221 }
222
223 const std::vector<AttributeList> &getAttributeLists() const {
224 return AttributeLists;
225 }
226
227 const std::vector<IndexAndAttrSet> &getAttributeGroups() const {
228 return AttributeGroups;
229 }
230
231 const ComdatSetType &getComdats() const { return Comdats; }
232 unsigned getComdatID(const Comdat *C) const;
233
234 /// getGlobalBasicBlockID - This returns the function-specific ID for the
235 /// specified basic block. This is relatively expensive information, so it
236 /// should only be used by rare constructs such as address-of-label.
237 unsigned getGlobalBasicBlockID(const BasicBlock *BB) const;
238
239 const Metadata *getDXILMetadata(const Metadata *M) const;
240
241 /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
242 /// use these two methods to get its data into the ValueEnumerator!
244
247
249
250private:
251
252 /// Reorder the reachable metadata.
253 ///
254 /// This is not just an optimization, but is mandatory for emitting MDString
255 /// correctly.
256 void organizeMetadata();
257
258 /// Drop the function tag from the transitive operands of the given node.
259 void dropFunctionFromMetadata(MetadataMapType::value_type &FirstMD);
260
261 /// Incorporate the function metadata.
262 ///
263 /// This should be called before enumerating LocalAsMetadata for the
264 /// function.
265 void incorporateFunctionMetadata(const Function &F);
266
267 /// Enumerate a single instance of metadata with the given function tag.
268 ///
269 /// If \c MD has already been enumerated, check that \c F matches its
270 /// function tag. If not, call \a dropFunctionFromMetadata().
271 ///
272 /// Otherwise, mark \c MD as visited. Assign it an ID, or just return it if
273 /// it's an \a MDNode.
274 const MDNode *enumerateMetadataImpl(unsigned F, const Metadata *MD);
275
276 unsigned getMetadataFunctionID(const Function *F) const;
277
278 /// Enumerate reachable metadata in (almost) post-order.
279 ///
280 /// Enumerate all the metadata reachable from MD. We want to minimize the
281 /// cost of reading bitcode records, and so the primary consideration is that
282 /// operands of uniqued nodes are resolved before the nodes are read. This
283 /// avoids re-uniquing them on the context and factors away RAUW support.
284 ///
285 /// This algorithm guarantees that subgraphs of uniqued nodes are in
286 /// post-order. Distinct subgraphs reachable only from a single uniqued node
287 /// will be in post-order.
288 ///
289 /// \note The relative order of a distinct and uniqued node is irrelevant.
290 /// \a organizeMetadata() will later partition distinct nodes ahead of
291 /// uniqued ones.
292 ///{
293 void EnumerateMetadata(const Function *F, const Metadata *MD);
294 void EnumerateMetadata(unsigned F, const Metadata *MD);
295 ///}
296
297 void EnumerateFunctionLocalMetadata(const Function &F,
298 const LocalAsMetadata *Local);
299 void EnumerateFunctionLocalMetadata(unsigned F, const LocalAsMetadata *Local);
300 void EnumerateFunctionLocalListMetadata(const Function &F,
301 const DIArgList *ArgList);
302 void EnumerateFunctionLocalListMetadata(unsigned F, const DIArgList *Arglist);
303 void EnumerateNamedMDNode(const NamedMDNode *NMD);
304 void EnumerateValue(const Value *V);
305 void EnumerateOperandType(const Value *V);
306 void EnumerateAttributes(AttributeList PAL);
307
308 void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
309 void EnumerateNamedMetadata(const Module &M);
310};
311
312} // end namespace dxil
313} // end namespace llvm
314
315#endif // LLVM_DXILWRITER_VALUEENUMERATOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
PrefixType
This file contains the simple types necessary to represent the attributes associated with functions a...
This file defines the DenseMap class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
#define T
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Definition DenseMap.h:75
BucketT value_type
Definition DenseMap.h:72
Metadata node.
Definition Metadata.h:1080
Root of the metadata hierarchy.
Definition Metadata.h:64
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
A tuple of MDNodes.
Definition Metadata.h:1760
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
UniqueVector - This class produces a sequential ID number (base 1) for each unique entry that is adde...
This class provides a symbol table of name/value pairs.
LLVM Value Representation.
Definition Value.h:75
ArrayRef< const Metadata * > getNonMDStrings() const
Get the non-MDString metadata for this block.
unsigned getValueID(const Value *V) const
std::pair< unsigned, AttributeSet > IndexAndAttrSet
Attribute groups as encoded in bitcode are almost AttributeSets, but they include the AttributeList i...
void setInstructionID(const Instruction *I)
unsigned getMetadataOrNullID(const Metadata *MD) const
const std::vector< IndexAndAttrSet > & getAttributeGroups() const
unsigned getComdatID(const Comdat *C) const
std::vector< std::pair< const Value *, unsigned > > ValueList
ArrayRef< const Metadata * > getMDStrings() const
Get the MDString metadata for this block.
bool hasMDs() const
Check whether the current block has any metadata to emit.
uint64_t computeBitsRequiredForTypeIndices() const
const ComdatSetType & getComdats() const
unsigned getAttributeListID(AttributeList PAL) const
unsigned getMetadataID(const Metadata *MD) const
ValueEnumerator & operator=(const ValueEnumerator &)=delete
void print(raw_ostream &OS, const MetadataMapType &Map, const char *Name) const
const TypeList & getTypes() const
const std::vector< AttributeList > & getAttributeLists() const
const Metadata * getDXILMetadata(const Metadata *M) const
void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const
std::vector< Type * > TypeList
void incorporateFunction(const Function &F)
incorporateFunction/purgeFunction - If you'd like to deal with a function, use these two methods to g...
unsigned getTypeID(Type *T) const
unsigned getInstructionID(const Instruction *I) const
const ValueList & getValues() const
ValueEnumerator(const ValueEnumerator &)=delete
unsigned getGlobalBasicBlockID(const BasicBlock *BB) const
getGlobalBasicBlockID - This returns the function-specific ID for the specified basic block.
void getFunctionConstantRange(unsigned &Start, unsigned &End) const
getFunctionConstantRange - Return the range of values that corresponds to function-local constants.
ValueEnumerator(const Module &M, Type *PrefixType, const DXILDebugInfoMap &DebugInfo)
const std::vector< const BasicBlock * > & getBasicBlocks() const
unsigned getAttributeGroupID(IndexAndAttrSet Group) const
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
std::vector< UseListOrder > UseListOrderStack
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
ArrayRef(const T &OneElt) -> ArrayRef< T >