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 Function &getDXILFunction(const Function &F) const;
240
241 const Instruction &getDXILInstruction(const Instruction &I) const;
242
243 const Metadata *getDXILMetadata(const Metadata *M) const;
244
245 const Value &getDXILValue(const Value &V) const;
246
247 /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
248 /// use these two methods to get its data into the ValueEnumerator!
250
253
255
256private:
257
258 /// Reorder the reachable metadata.
259 ///
260 /// This is not just an optimization, but is mandatory for emitting MDString
261 /// correctly.
262 void organizeMetadata();
263
264 /// Drop the function tag from the transitive operands of the given node.
265 void dropFunctionFromMetadata(MetadataMapType::value_type &FirstMD);
266
267 /// Incorporate the function metadata.
268 ///
269 /// This should be called before enumerating LocalAsMetadata for the
270 /// function.
271 void incorporateFunctionMetadata(const Function &F);
272
273 /// Enumerate a single instance of metadata with the given function tag.
274 ///
275 /// If \c MD has already been enumerated, check that \c F matches its
276 /// function tag. If not, call \a dropFunctionFromMetadata().
277 ///
278 /// Otherwise, mark \c MD as visited. Assign it an ID, or just return it if
279 /// it's an \a MDNode.
280 const MDNode *enumerateMetadataImpl(unsigned F, const Metadata *MD);
281
282 unsigned getMetadataFunctionID(const Function *F) const;
283
284 /// Enumerate reachable metadata in (almost) post-order.
285 ///
286 /// Enumerate all the metadata reachable from MD. We want to minimize the
287 /// cost of reading bitcode records, and so the primary consideration is that
288 /// operands of uniqued nodes are resolved before the nodes are read. This
289 /// avoids re-uniquing them on the context and factors away RAUW support.
290 ///
291 /// This algorithm guarantees that subgraphs of uniqued nodes are in
292 /// post-order. Distinct subgraphs reachable only from a single uniqued node
293 /// will be in post-order.
294 ///
295 /// \note The relative order of a distinct and uniqued node is irrelevant.
296 /// \a organizeMetadata() will later partition distinct nodes ahead of
297 /// uniqued ones.
298 ///{
299 void EnumerateMetadata(const Function *F, const Metadata *MD);
300 void EnumerateMetadata(unsigned F, const Metadata *MD);
301 ///}
302
303 void EnumerateFunctionLocalMetadata(const Function &F,
304 const LocalAsMetadata *Local);
305 void EnumerateFunctionLocalMetadata(unsigned F, const LocalAsMetadata *Local);
306 void EnumerateFunctionLocalListMetadata(const Function &F,
307 const DIArgList *ArgList);
308 void EnumerateFunctionLocalListMetadata(unsigned F, const DIArgList *Arglist);
309 void EnumerateNamedMDNode(const NamedMDNode *NMD);
310 void EnumerateValue(const Value *V);
311 void EnumerateOperandType(const Value *V);
312 void EnumerateAttributes(AttributeList PAL);
313
314 void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
315 void EnumerateNamedMetadata(const Module &M);
316};
317
318} // end namespace dxil
319} // end namespace llvm
320
321#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
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:79
BucketT value_type
Definition DenseMap.h:76
Metadata node.
Definition Metadata.h:1075
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:1755
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...
const Value & getDXILValue(const Value &V) const
const Instruction & getDXILInstruction(const Instruction &I) const
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 Function & getDXILFunction(const Function &F) 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 >