12cab237bSDimitry Andric //===- ValueEnumerator.cpp - Number values and types for bitcode writer ---===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements the ValueEnumerator class.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky
14f22ef01cSRoman Divacky #include "ValueEnumerator.h"
152cab237bSDimitry Andric #include "llvm/ADT/DenseMap.h"
162cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
174ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
182cab237bSDimitry Andric #include "llvm/IR/Argument.h"
192cab237bSDimitry Andric #include "llvm/IR/Attributes.h"
202cab237bSDimitry Andric #include "llvm/IR/BasicBlock.h"
212cab237bSDimitry Andric #include "llvm/IR/Constant.h"
22ff0cc061SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
23139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h"
242cab237bSDimitry Andric #include "llvm/IR/Function.h"
252cab237bSDimitry Andric #include "llvm/IR/GlobalAlias.h"
262cab237bSDimitry Andric #include "llvm/IR/GlobalIFunc.h"
272cab237bSDimitry Andric #include "llvm/IR/GlobalObject.h"
282cab237bSDimitry Andric #include "llvm/IR/GlobalValue.h"
292cab237bSDimitry Andric #include "llvm/IR/GlobalVariable.h"
302cab237bSDimitry Andric #include "llvm/IR/Instruction.h"
31139f7f9bSDimitry Andric #include "llvm/IR/Instructions.h"
322cab237bSDimitry Andric #include "llvm/IR/Metadata.h"
33139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
342cab237bSDimitry Andric #include "llvm/IR/Type.h"
352cab237bSDimitry Andric #include "llvm/IR/Use.h"
3639d628a0SDimitry Andric #include "llvm/IR/UseListOrder.h"
372cab237bSDimitry Andric #include "llvm/IR/User.h"
382cab237bSDimitry Andric #include "llvm/IR/Value.h"
39139f7f9bSDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
402cab237bSDimitry Andric #include "llvm/Support/Casting.h"
412cab237bSDimitry Andric #include "llvm/Support/Compiler.h"
42dff0c46cSDimitry Andric #include "llvm/Support/Debug.h"
432cab237bSDimitry Andric #include "llvm/Support/MathExtras.h"
44dff0c46cSDimitry Andric #include "llvm/Support/raw_ostream.h"
45f22ef01cSRoman Divacky #include <algorithm>
462cab237bSDimitry Andric #include <cassert>
472cab237bSDimitry Andric #include <cstddef>
482cab237bSDimitry Andric #include <iterator>
492cab237bSDimitry Andric #include <tuple>
502cab237bSDimitry Andric #include <utility>
512cab237bSDimitry Andric #include <vector>
522cab237bSDimitry Andric
53f22ef01cSRoman Divacky using namespace llvm;
54f22ef01cSRoman Divacky
5539d628a0SDimitry Andric namespace {
562cab237bSDimitry Andric
5739d628a0SDimitry Andric struct OrderMap {
5839d628a0SDimitry Andric DenseMap<const Value *, std::pair<unsigned, bool>> IDs;
592cab237bSDimitry Andric unsigned LastGlobalConstantID = 0;
602cab237bSDimitry Andric unsigned LastGlobalValueID = 0;
6139d628a0SDimitry Andric
622cab237bSDimitry Andric OrderMap() = default;
6339d628a0SDimitry Andric
isGlobalConstant__anon58675e290111::OrderMap6439d628a0SDimitry Andric bool isGlobalConstant(unsigned ID) const {
6539d628a0SDimitry Andric return ID <= LastGlobalConstantID;
6639d628a0SDimitry Andric }
672cab237bSDimitry Andric
isGlobalValue__anon58675e290111::OrderMap6839d628a0SDimitry Andric bool isGlobalValue(unsigned ID) const {
6939d628a0SDimitry Andric return ID <= LastGlobalValueID && !isGlobalConstant(ID);
7039d628a0SDimitry Andric }
7139d628a0SDimitry Andric
size__anon58675e290111::OrderMap7239d628a0SDimitry Andric unsigned size() const { return IDs.size(); }
operator []__anon58675e290111::OrderMap7339d628a0SDimitry Andric std::pair<unsigned, bool> &operator[](const Value *V) { return IDs[V]; }
742cab237bSDimitry Andric
lookup__anon58675e290111::OrderMap7539d628a0SDimitry Andric std::pair<unsigned, bool> lookup(const Value *V) const {
7639d628a0SDimitry Andric return IDs.lookup(V);
7739d628a0SDimitry Andric }
782cab237bSDimitry Andric
index__anon58675e290111::OrderMap7939d628a0SDimitry Andric void index(const Value *V) {
8039d628a0SDimitry Andric // Explicitly sequence get-size and insert-value operations to avoid UB.
8139d628a0SDimitry Andric unsigned ID = IDs.size() + 1;
8239d628a0SDimitry Andric IDs[V].first = ID;
8339d628a0SDimitry Andric }
8439d628a0SDimitry Andric };
852cab237bSDimitry Andric
862cab237bSDimitry Andric } // end anonymous namespace
8739d628a0SDimitry Andric
orderValue(const Value * V,OrderMap & OM)8839d628a0SDimitry Andric static void orderValue(const Value *V, OrderMap &OM) {
8939d628a0SDimitry Andric if (OM.lookup(V).first)
9039d628a0SDimitry Andric return;
9139d628a0SDimitry Andric
9239d628a0SDimitry Andric if (const Constant *C = dyn_cast<Constant>(V))
9339d628a0SDimitry Andric if (C->getNumOperands() && !isa<GlobalValue>(C))
9439d628a0SDimitry Andric for (const Value *Op : C->operands())
9539d628a0SDimitry Andric if (!isa<BasicBlock>(Op) && !isa<GlobalValue>(Op))
9639d628a0SDimitry Andric orderValue(Op, OM);
9739d628a0SDimitry Andric
9839d628a0SDimitry Andric // Note: we cannot cache this lookup above, since inserting into the map
9939d628a0SDimitry Andric // changes the map's size, and thus affects the other IDs.
10039d628a0SDimitry Andric OM.index(V);
10139d628a0SDimitry Andric }
10239d628a0SDimitry Andric
orderModule(const Module & M)10339d628a0SDimitry Andric static OrderMap orderModule(const Module &M) {
10439d628a0SDimitry Andric // This needs to match the order used by ValueEnumerator::ValueEnumerator()
10539d628a0SDimitry Andric // and ValueEnumerator::incorporateFunction().
10639d628a0SDimitry Andric OrderMap OM;
10739d628a0SDimitry Andric
10839d628a0SDimitry Andric // In the reader, initializers of GlobalValues are set *after* all the
10939d628a0SDimitry Andric // globals have been read. Rather than awkwardly modeling this behaviour
11039d628a0SDimitry Andric // directly in predictValueUseListOrderImpl(), just assign IDs to
11139d628a0SDimitry Andric // initializers of GlobalValues before GlobalValues themselves to model this
11239d628a0SDimitry Andric // implicitly.
11339d628a0SDimitry Andric for (const GlobalVariable &G : M.globals())
11439d628a0SDimitry Andric if (G.hasInitializer())
11539d628a0SDimitry Andric if (!isa<GlobalValue>(G.getInitializer()))
11639d628a0SDimitry Andric orderValue(G.getInitializer(), OM);
11739d628a0SDimitry Andric for (const GlobalAlias &A : M.aliases())
11839d628a0SDimitry Andric if (!isa<GlobalValue>(A.getAliasee()))
11939d628a0SDimitry Andric orderValue(A.getAliasee(), OM);
1203ca95b02SDimitry Andric for (const GlobalIFunc &I : M.ifuncs())
1213ca95b02SDimitry Andric if (!isa<GlobalValue>(I.getResolver()))
1223ca95b02SDimitry Andric orderValue(I.getResolver(), OM);
12339d628a0SDimitry Andric for (const Function &F : M) {
1247d523365SDimitry Andric for (const Use &U : F.operands())
1257d523365SDimitry Andric if (!isa<GlobalValue>(U.get()))
1267d523365SDimitry Andric orderValue(U.get(), OM);
12739d628a0SDimitry Andric }
12839d628a0SDimitry Andric OM.LastGlobalConstantID = OM.size();
12939d628a0SDimitry Andric
13039d628a0SDimitry Andric // Initializers of GlobalValues are processed in
13139d628a0SDimitry Andric // BitcodeReader::ResolveGlobalAndAliasInits(). Match the order there rather
13239d628a0SDimitry Andric // than ValueEnumerator, and match the code in predictValueUseListOrderImpl()
13339d628a0SDimitry Andric // by giving IDs in reverse order.
13439d628a0SDimitry Andric //
13539d628a0SDimitry Andric // Since GlobalValues never reference each other directly (just through
13639d628a0SDimitry Andric // initializers), their relative IDs only matter for determining order of
13739d628a0SDimitry Andric // uses in their initializers.
13839d628a0SDimitry Andric for (const Function &F : M)
13939d628a0SDimitry Andric orderValue(&F, OM);
14039d628a0SDimitry Andric for (const GlobalAlias &A : M.aliases())
14139d628a0SDimitry Andric orderValue(&A, OM);
1423ca95b02SDimitry Andric for (const GlobalIFunc &I : M.ifuncs())
1433ca95b02SDimitry Andric orderValue(&I, OM);
14439d628a0SDimitry Andric for (const GlobalVariable &G : M.globals())
14539d628a0SDimitry Andric orderValue(&G, OM);
14639d628a0SDimitry Andric OM.LastGlobalValueID = OM.size();
14739d628a0SDimitry Andric
14839d628a0SDimitry Andric for (const Function &F : M) {
14939d628a0SDimitry Andric if (F.isDeclaration())
15039d628a0SDimitry Andric continue;
15139d628a0SDimitry Andric // Here we need to match the union of ValueEnumerator::incorporateFunction()
15239d628a0SDimitry Andric // and WriteFunction(). Basic blocks are implicitly declared before
15339d628a0SDimitry Andric // anything else (by declaring their size).
15439d628a0SDimitry Andric for (const BasicBlock &BB : F)
15539d628a0SDimitry Andric orderValue(&BB, OM);
15639d628a0SDimitry Andric for (const Argument &A : F.args())
15739d628a0SDimitry Andric orderValue(&A, OM);
15839d628a0SDimitry Andric for (const BasicBlock &BB : F)
15939d628a0SDimitry Andric for (const Instruction &I : BB)
16039d628a0SDimitry Andric for (const Value *Op : I.operands())
16139d628a0SDimitry Andric if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
16239d628a0SDimitry Andric isa<InlineAsm>(*Op))
16339d628a0SDimitry Andric orderValue(Op, OM);
16439d628a0SDimitry Andric for (const BasicBlock &BB : F)
16539d628a0SDimitry Andric for (const Instruction &I : BB)
16639d628a0SDimitry Andric orderValue(&I, OM);
16739d628a0SDimitry Andric }
16839d628a0SDimitry Andric return OM;
16939d628a0SDimitry Andric }
17039d628a0SDimitry Andric
predictValueUseListOrderImpl(const Value * V,const Function * F,unsigned ID,const OrderMap & OM,UseListOrderStack & Stack)17139d628a0SDimitry Andric static void predictValueUseListOrderImpl(const Value *V, const Function *F,
17239d628a0SDimitry Andric unsigned ID, const OrderMap &OM,
17339d628a0SDimitry Andric UseListOrderStack &Stack) {
17439d628a0SDimitry Andric // Predict use-list order for this one.
1752cab237bSDimitry Andric using Entry = std::pair<const Use *, unsigned>;
17639d628a0SDimitry Andric SmallVector<Entry, 64> List;
17739d628a0SDimitry Andric for (const Use &U : V->uses())
17839d628a0SDimitry Andric // Check if this user will be serialized.
17939d628a0SDimitry Andric if (OM.lookup(U.getUser()).first)
18039d628a0SDimitry Andric List.push_back(std::make_pair(&U, List.size()));
18139d628a0SDimitry Andric
18239d628a0SDimitry Andric if (List.size() < 2)
18339d628a0SDimitry Andric // We may have lost some users.
18439d628a0SDimitry Andric return;
18539d628a0SDimitry Andric
18639d628a0SDimitry Andric bool IsGlobalValue = OM.isGlobalValue(ID);
187*b5893f02SDimitry Andric llvm::sort(List, [&](const Entry &L, const Entry &R) {
18839d628a0SDimitry Andric const Use *LU = L.first;
18939d628a0SDimitry Andric const Use *RU = R.first;
19039d628a0SDimitry Andric if (LU == RU)
19139d628a0SDimitry Andric return false;
19239d628a0SDimitry Andric
19339d628a0SDimitry Andric auto LID = OM.lookup(LU->getUser()).first;
19439d628a0SDimitry Andric auto RID = OM.lookup(RU->getUser()).first;
19539d628a0SDimitry Andric
19639d628a0SDimitry Andric // Global values are processed in reverse order.
19739d628a0SDimitry Andric //
19839d628a0SDimitry Andric // Moreover, initializers of GlobalValues are set *after* all the globals
19939d628a0SDimitry Andric // have been read (despite having earlier IDs). Rather than awkwardly
20039d628a0SDimitry Andric // modeling this behaviour here, orderModule() has assigned IDs to
20139d628a0SDimitry Andric // initializers of GlobalValues before GlobalValues themselves.
20239d628a0SDimitry Andric if (OM.isGlobalValue(LID) && OM.isGlobalValue(RID))
20339d628a0SDimitry Andric return LID < RID;
20439d628a0SDimitry Andric
20539d628a0SDimitry Andric // If ID is 4, then expect: 7 6 5 1 2 3.
20639d628a0SDimitry Andric if (LID < RID) {
20739d628a0SDimitry Andric if (RID <= ID)
20839d628a0SDimitry Andric if (!IsGlobalValue) // GlobalValue uses don't get reversed.
20939d628a0SDimitry Andric return true;
21039d628a0SDimitry Andric return false;
21139d628a0SDimitry Andric }
21239d628a0SDimitry Andric if (RID < LID) {
21339d628a0SDimitry Andric if (LID <= ID)
21439d628a0SDimitry Andric if (!IsGlobalValue) // GlobalValue uses don't get reversed.
21539d628a0SDimitry Andric return false;
21639d628a0SDimitry Andric return true;
21739d628a0SDimitry Andric }
21839d628a0SDimitry Andric
21939d628a0SDimitry Andric // LID and RID are equal, so we have different operands of the same user.
22039d628a0SDimitry Andric // Assume operands are added in order for all instructions.
22139d628a0SDimitry Andric if (LID <= ID)
22239d628a0SDimitry Andric if (!IsGlobalValue) // GlobalValue uses don't get reversed.
22339d628a0SDimitry Andric return LU->getOperandNo() < RU->getOperandNo();
22439d628a0SDimitry Andric return LU->getOperandNo() > RU->getOperandNo();
22539d628a0SDimitry Andric });
22639d628a0SDimitry Andric
22739d628a0SDimitry Andric if (std::is_sorted(
22839d628a0SDimitry Andric List.begin(), List.end(),
22939d628a0SDimitry Andric [](const Entry &L, const Entry &R) { return L.second < R.second; }))
23039d628a0SDimitry Andric // Order is already correct.
23139d628a0SDimitry Andric return;
23239d628a0SDimitry Andric
23339d628a0SDimitry Andric // Store the shuffle.
23439d628a0SDimitry Andric Stack.emplace_back(V, F, List.size());
23539d628a0SDimitry Andric assert(List.size() == Stack.back().Shuffle.size() && "Wrong size");
23639d628a0SDimitry Andric for (size_t I = 0, E = List.size(); I != E; ++I)
23739d628a0SDimitry Andric Stack.back().Shuffle[I] = List[I].second;
23839d628a0SDimitry Andric }
23939d628a0SDimitry Andric
predictValueUseListOrder(const Value * V,const Function * F,OrderMap & OM,UseListOrderStack & Stack)24039d628a0SDimitry Andric static void predictValueUseListOrder(const Value *V, const Function *F,
24139d628a0SDimitry Andric OrderMap &OM, UseListOrderStack &Stack) {
24239d628a0SDimitry Andric auto &IDPair = OM[V];
24339d628a0SDimitry Andric assert(IDPair.first && "Unmapped value");
24439d628a0SDimitry Andric if (IDPair.second)
24539d628a0SDimitry Andric // Already predicted.
24639d628a0SDimitry Andric return;
24739d628a0SDimitry Andric
24839d628a0SDimitry Andric // Do the actual prediction.
24939d628a0SDimitry Andric IDPair.second = true;
25039d628a0SDimitry Andric if (!V->use_empty() && std::next(V->use_begin()) != V->use_end())
25139d628a0SDimitry Andric predictValueUseListOrderImpl(V, F, IDPair.first, OM, Stack);
25239d628a0SDimitry Andric
25339d628a0SDimitry Andric // Recursive descent into constants.
25439d628a0SDimitry Andric if (const Constant *C = dyn_cast<Constant>(V))
25539d628a0SDimitry Andric if (C->getNumOperands()) // Visit GlobalValues.
25639d628a0SDimitry Andric for (const Value *Op : C->operands())
25739d628a0SDimitry Andric if (isa<Constant>(Op)) // Visit GlobalValues.
25839d628a0SDimitry Andric predictValueUseListOrder(Op, F, OM, Stack);
25939d628a0SDimitry Andric }
26039d628a0SDimitry Andric
predictUseListOrder(const Module & M)26139d628a0SDimitry Andric static UseListOrderStack predictUseListOrder(const Module &M) {
26239d628a0SDimitry Andric OrderMap OM = orderModule(M);
26339d628a0SDimitry Andric
26439d628a0SDimitry Andric // Use-list orders need to be serialized after all the users have been added
26539d628a0SDimitry Andric // to a value, or else the shuffles will be incomplete. Store them per
26639d628a0SDimitry Andric // function in a stack.
26739d628a0SDimitry Andric //
26839d628a0SDimitry Andric // Aside from function order, the order of values doesn't matter much here.
26939d628a0SDimitry Andric UseListOrderStack Stack;
27039d628a0SDimitry Andric
27139d628a0SDimitry Andric // We want to visit the functions backward now so we can list function-local
27239d628a0SDimitry Andric // constants in the last Function they're used in. Module-level constants
27339d628a0SDimitry Andric // have already been visited above.
27439d628a0SDimitry Andric for (auto I = M.rbegin(), E = M.rend(); I != E; ++I) {
27539d628a0SDimitry Andric const Function &F = *I;
27639d628a0SDimitry Andric if (F.isDeclaration())
27739d628a0SDimitry Andric continue;
27839d628a0SDimitry Andric for (const BasicBlock &BB : F)
27939d628a0SDimitry Andric predictValueUseListOrder(&BB, &F, OM, Stack);
28039d628a0SDimitry Andric for (const Argument &A : F.args())
28139d628a0SDimitry Andric predictValueUseListOrder(&A, &F, OM, Stack);
28239d628a0SDimitry Andric for (const BasicBlock &BB : F)
28339d628a0SDimitry Andric for (const Instruction &I : BB)
28439d628a0SDimitry Andric for (const Value *Op : I.operands())
28539d628a0SDimitry Andric if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues.
28639d628a0SDimitry Andric predictValueUseListOrder(Op, &F, OM, Stack);
28739d628a0SDimitry Andric for (const BasicBlock &BB : F)
28839d628a0SDimitry Andric for (const Instruction &I : BB)
28939d628a0SDimitry Andric predictValueUseListOrder(&I, &F, OM, Stack);
29039d628a0SDimitry Andric }
29139d628a0SDimitry Andric
29239d628a0SDimitry Andric // Visit globals last, since the module-level use-list block will be seen
29339d628a0SDimitry Andric // before the function bodies are processed.
29439d628a0SDimitry Andric for (const GlobalVariable &G : M.globals())
29539d628a0SDimitry Andric predictValueUseListOrder(&G, nullptr, OM, Stack);
29639d628a0SDimitry Andric for (const Function &F : M)
29739d628a0SDimitry Andric predictValueUseListOrder(&F, nullptr, OM, Stack);
29839d628a0SDimitry Andric for (const GlobalAlias &A : M.aliases())
29939d628a0SDimitry Andric predictValueUseListOrder(&A, nullptr, OM, Stack);
3003ca95b02SDimitry Andric for (const GlobalIFunc &I : M.ifuncs())
3013ca95b02SDimitry Andric predictValueUseListOrder(&I, nullptr, OM, Stack);
30239d628a0SDimitry Andric for (const GlobalVariable &G : M.globals())
30339d628a0SDimitry Andric if (G.hasInitializer())
30439d628a0SDimitry Andric predictValueUseListOrder(G.getInitializer(), nullptr, OM, Stack);
30539d628a0SDimitry Andric for (const GlobalAlias &A : M.aliases())
30639d628a0SDimitry Andric predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack);
3073ca95b02SDimitry Andric for (const GlobalIFunc &I : M.ifuncs())
3083ca95b02SDimitry Andric predictValueUseListOrder(I.getResolver(), nullptr, OM, Stack);
30939d628a0SDimitry Andric for (const Function &F : M) {
3107d523365SDimitry Andric for (const Use &U : F.operands())
3117d523365SDimitry Andric predictValueUseListOrder(U.get(), nullptr, OM, Stack);
31239d628a0SDimitry Andric }
31339d628a0SDimitry Andric
31439d628a0SDimitry Andric return Stack;
31539d628a0SDimitry Andric }
31639d628a0SDimitry Andric
isIntOrIntVectorValue(const std::pair<const Value *,unsigned> & V)317139f7f9bSDimitry Andric static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
318139f7f9bSDimitry Andric return V.first->getType()->isIntOrIntVectorTy();
319f22ef01cSRoman Divacky }
320f22ef01cSRoman Divacky
ValueEnumerator(const Module & M,bool ShouldPreserveUseListOrder)321ff0cc061SDimitry Andric ValueEnumerator::ValueEnumerator(const Module &M,
322ff0cc061SDimitry Andric bool ShouldPreserveUseListOrder)
3233ca95b02SDimitry Andric : ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
324ff0cc061SDimitry Andric if (ShouldPreserveUseListOrder)
32539d628a0SDimitry Andric UseListOrders = predictUseListOrder(M);
32639d628a0SDimitry Andric
327f22ef01cSRoman Divacky // Enumerate the global variables.
3288f0fd8f6SDimitry Andric for (const GlobalVariable &GV : M.globals())
3298f0fd8f6SDimitry Andric EnumerateValue(&GV);
330f22ef01cSRoman Divacky
331f22ef01cSRoman Divacky // Enumerate the functions.
3328f0fd8f6SDimitry Andric for (const Function & F : M) {
3338f0fd8f6SDimitry Andric EnumerateValue(&F);
3348f0fd8f6SDimitry Andric EnumerateAttributes(F.getAttributes());
335f22ef01cSRoman Divacky }
336f22ef01cSRoman Divacky
337f22ef01cSRoman Divacky // Enumerate the aliases.
3388f0fd8f6SDimitry Andric for (const GlobalAlias &GA : M.aliases())
3398f0fd8f6SDimitry Andric EnumerateValue(&GA);
340f22ef01cSRoman Divacky
3413ca95b02SDimitry Andric // Enumerate the ifuncs.
3423ca95b02SDimitry Andric for (const GlobalIFunc &GIF : M.ifuncs())
3433ca95b02SDimitry Andric EnumerateValue(&GIF);
3443ca95b02SDimitry Andric
345f22ef01cSRoman Divacky // Remember what is the cutoff between globalvalue's and other constants.
346f22ef01cSRoman Divacky unsigned FirstConstant = Values.size();
347f22ef01cSRoman Divacky
3485517e702SDimitry Andric // Enumerate the global variable initializers and attributes.
3495517e702SDimitry Andric for (const GlobalVariable &GV : M.globals()) {
3508f0fd8f6SDimitry Andric if (GV.hasInitializer())
3518f0fd8f6SDimitry Andric EnumerateValue(GV.getInitializer());
3525517e702SDimitry Andric if (GV.hasAttributes())
3535517e702SDimitry Andric EnumerateAttributes(GV.getAttributesAsList(AttributeList::FunctionIndex));
3545517e702SDimitry Andric }
355f22ef01cSRoman Divacky
356f22ef01cSRoman Divacky // Enumerate the aliasees.
3578f0fd8f6SDimitry Andric for (const GlobalAlias &GA : M.aliases())
3588f0fd8f6SDimitry Andric EnumerateValue(GA.getAliasee());
359f22ef01cSRoman Divacky
3603ca95b02SDimitry Andric // Enumerate the ifunc resolvers.
3613ca95b02SDimitry Andric for (const GlobalIFunc &GIF : M.ifuncs())
3623ca95b02SDimitry Andric EnumerateValue(GIF.getResolver());
3633ca95b02SDimitry Andric
3647d523365SDimitry Andric // Enumerate any optional Function data.
3658f0fd8f6SDimitry Andric for (const Function &F : M)
3667d523365SDimitry Andric for (const Use &U : F.operands())
3677d523365SDimitry Andric EnumerateValue(U.get());
36839d628a0SDimitry Andric
36939d628a0SDimitry Andric // Enumerate the metadata type.
37039d628a0SDimitry Andric //
37139d628a0SDimitry Andric // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode
37239d628a0SDimitry Andric // only encodes the metadata type when it's used as a value.
37339d628a0SDimitry Andric EnumerateType(Type::getMetadataTy(M.getContext()));
37439d628a0SDimitry Andric
375f22ef01cSRoman Divacky // Insert constants and metadata that are named at module level into the slot
376f22ef01cSRoman Divacky // pool so that the module symbol table can refer to them...
37739d628a0SDimitry Andric EnumerateValueSymbolTable(M.getValueSymbolTable());
378e580952dSDimitry Andric EnumerateNamedMetadata(M);
379f22ef01cSRoman Divacky
380f22ef01cSRoman Divacky SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
3813ca95b02SDimitry Andric for (const GlobalVariable &GV : M.globals()) {
3823ca95b02SDimitry Andric MDs.clear();
3833ca95b02SDimitry Andric GV.getAllMetadata(MDs);
3843ca95b02SDimitry Andric for (const auto &I : MDs)
3853ca95b02SDimitry Andric // FIXME: Pass GV to EnumerateMetadata and arrange for the bitcode writer
3863ca95b02SDimitry Andric // to write metadata to the global variable's own metadata block
3873ca95b02SDimitry Andric // (PR28134).
3883ca95b02SDimitry Andric EnumerateMetadata(nullptr, I.second);
3893ca95b02SDimitry Andric }
390f22ef01cSRoman Divacky
391f22ef01cSRoman Divacky // Enumerate types used by function bodies and argument lists.
39239d628a0SDimitry Andric for (const Function &F : M) {
39391bc56edSDimitry Andric for (const Argument &A : F.args())
39491bc56edSDimitry Andric EnumerateType(A.getType());
395f22ef01cSRoman Divacky
396ff0cc061SDimitry Andric // Enumerate metadata attached to this function.
3973ca95b02SDimitry Andric MDs.clear();
398ff0cc061SDimitry Andric F.getAllMetadata(MDs);
399ff0cc061SDimitry Andric for (const auto &I : MDs)
4003ca95b02SDimitry Andric EnumerateMetadata(F.isDeclaration() ? nullptr : &F, I.second);
401ff0cc061SDimitry Andric
40291bc56edSDimitry Andric for (const BasicBlock &BB : F)
40391bc56edSDimitry Andric for (const Instruction &I : BB) {
40491bc56edSDimitry Andric for (const Use &Op : I.operands()) {
40539d628a0SDimitry Andric auto *MD = dyn_cast<MetadataAsValue>(&Op);
40639d628a0SDimitry Andric if (!MD) {
40791bc56edSDimitry Andric EnumerateOperandType(Op);
40839d628a0SDimitry Andric continue;
40939d628a0SDimitry Andric }
41039d628a0SDimitry Andric
41139d628a0SDimitry Andric // Local metadata is enumerated during function-incorporation.
41239d628a0SDimitry Andric if (isa<LocalAsMetadata>(MD->getMetadata()))
41339d628a0SDimitry Andric continue;
41439d628a0SDimitry Andric
4153ca95b02SDimitry Andric EnumerateMetadata(&F, MD->getMetadata());
416f22ef01cSRoman Divacky }
41791bc56edSDimitry Andric EnumerateType(I.getType());
41891bc56edSDimitry Andric if (const CallInst *CI = dyn_cast<CallInst>(&I))
419f22ef01cSRoman Divacky EnumerateAttributes(CI->getAttributes());
42091bc56edSDimitry Andric else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I))
421f22ef01cSRoman Divacky EnumerateAttributes(II->getAttributes());
422f22ef01cSRoman Divacky
423f22ef01cSRoman Divacky // Enumerate metadata attached with this instruction.
424f22ef01cSRoman Divacky MDs.clear();
42591bc56edSDimitry Andric I.getAllMetadataOtherThanDebugLoc(MDs);
426f22ef01cSRoman Divacky for (unsigned i = 0, e = MDs.size(); i != e; ++i)
4273ca95b02SDimitry Andric EnumerateMetadata(&F, MDs[i].second);
428f22ef01cSRoman Divacky
429ff0cc061SDimitry Andric // Don't enumerate the location directly -- it has a special record
430ff0cc061SDimitry Andric // type -- but enumerate its operands.
431ff0cc061SDimitry Andric if (DILocation *L = I.getDebugLoc())
4323ca95b02SDimitry Andric for (const Metadata *Op : L->operands())
4333ca95b02SDimitry Andric EnumerateMetadata(&F, Op);
434f22ef01cSRoman Divacky }
435f22ef01cSRoman Divacky }
436f22ef01cSRoman Divacky
437f22ef01cSRoman Divacky // Optimize constant ordering.
438f22ef01cSRoman Divacky OptimizeConstants(FirstConstant, Values.size());
4393ca95b02SDimitry Andric
4403ca95b02SDimitry Andric // Organize metadata ordering.
4413ca95b02SDimitry Andric organizeMetadata();
4423b0f4066SDimitry Andric }
4433b0f4066SDimitry Andric
getInstructionID(const Instruction * Inst) const444f22ef01cSRoman Divacky unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {
445f22ef01cSRoman Divacky InstructionMapType::const_iterator I = InstructionMap.find(Inst);
446f22ef01cSRoman Divacky assert(I != InstructionMap.end() && "Instruction is not mapped!");
447f22ef01cSRoman Divacky return I->second;
448f22ef01cSRoman Divacky }
449f22ef01cSRoman Divacky
getComdatID(const Comdat * C) const45091bc56edSDimitry Andric unsigned ValueEnumerator::getComdatID(const Comdat *C) const {
45191bc56edSDimitry Andric unsigned ComdatID = Comdats.idFor(C);
45291bc56edSDimitry Andric assert(ComdatID && "Comdat not found!");
45391bc56edSDimitry Andric return ComdatID;
45491bc56edSDimitry Andric }
45591bc56edSDimitry Andric
setInstructionID(const Instruction * I)456f22ef01cSRoman Divacky void ValueEnumerator::setInstructionID(const Instruction *I) {
457f22ef01cSRoman Divacky InstructionMap[I] = InstructionCount++;
458f22ef01cSRoman Divacky }
459f22ef01cSRoman Divacky
getValueID(const Value * V) const460f22ef01cSRoman Divacky unsigned ValueEnumerator::getValueID(const Value *V) const {
46139d628a0SDimitry Andric if (auto *MD = dyn_cast<MetadataAsValue>(V))
46239d628a0SDimitry Andric return getMetadataID(MD->getMetadata());
463f22ef01cSRoman Divacky
464f22ef01cSRoman Divacky ValueMapType::const_iterator I = ValueMap.find(V);
465f22ef01cSRoman Divacky assert(I != ValueMap.end() && "Value not in slotcalculator!");
466f22ef01cSRoman Divacky return I->second-1;
467f22ef01cSRoman Divacky }
468f22ef01cSRoman Divacky
4697a7e6055SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const4703ca95b02SDimitry Andric LLVM_DUMP_METHOD void ValueEnumerator::dump() const {
471dff0c46cSDimitry Andric print(dbgs(), ValueMap, "Default");
472dff0c46cSDimitry Andric dbgs() << '\n';
4737d523365SDimitry Andric print(dbgs(), MetadataMap, "MetaData");
474dff0c46cSDimitry Andric dbgs() << '\n';
475dff0c46cSDimitry Andric }
4767a7e6055SDimitry Andric #endif
477dff0c46cSDimitry Andric
print(raw_ostream & OS,const ValueMapType & Map,const char * Name) const478dff0c46cSDimitry Andric void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,
479dff0c46cSDimitry Andric const char *Name) const {
480dff0c46cSDimitry Andric OS << "Map Name: " << Name << "\n";
481dff0c46cSDimitry Andric OS << "Size: " << Map.size() << "\n";
482dff0c46cSDimitry Andric for (ValueMapType::const_iterator I = Map.begin(),
483dff0c46cSDimitry Andric E = Map.end(); I != E; ++I) {
484dff0c46cSDimitry Andric const Value *V = I->first;
485dff0c46cSDimitry Andric if (V->hasName())
486dff0c46cSDimitry Andric OS << "Value: " << V->getName();
487dff0c46cSDimitry Andric else
488dff0c46cSDimitry Andric OS << "Value: [null]\n";
4897a7e6055SDimitry Andric V->print(errs());
4907a7e6055SDimitry Andric errs() << '\n';
491dff0c46cSDimitry Andric
4924ba319b5SDimitry Andric OS << " Uses(" << V->getNumUses() << "):";
49391bc56edSDimitry Andric for (const Use &U : V->uses()) {
49491bc56edSDimitry Andric if (&U != &*V->use_begin())
495dff0c46cSDimitry Andric OS << ",";
49691bc56edSDimitry Andric if(U->hasName())
49791bc56edSDimitry Andric OS << " " << U->getName();
498dff0c46cSDimitry Andric else
499dff0c46cSDimitry Andric OS << " [null]";
500dff0c46cSDimitry Andric
501dff0c46cSDimitry Andric }
502dff0c46cSDimitry Andric OS << "\n\n";
503dff0c46cSDimitry Andric }
504dff0c46cSDimitry Andric }
505dff0c46cSDimitry Andric
print(raw_ostream & OS,const MetadataMapType & Map,const char * Name) const50639d628a0SDimitry Andric void ValueEnumerator::print(raw_ostream &OS, const MetadataMapType &Map,
50739d628a0SDimitry Andric const char *Name) const {
50839d628a0SDimitry Andric OS << "Map Name: " << Name << "\n";
50939d628a0SDimitry Andric OS << "Size: " << Map.size() << "\n";
51039d628a0SDimitry Andric for (auto I = Map.begin(), E = Map.end(); I != E; ++I) {
51139d628a0SDimitry Andric const Metadata *MD = I->first;
5123ca95b02SDimitry Andric OS << "Metadata: slot = " << I->second.ID << "\n";
5133ca95b02SDimitry Andric OS << "Metadata: function = " << I->second.F << "\n";
51439d628a0SDimitry Andric MD->print(OS);
5153ca95b02SDimitry Andric OS << "\n";
51639d628a0SDimitry Andric }
51739d628a0SDimitry Andric }
51839d628a0SDimitry Andric
519f22ef01cSRoman Divacky /// OptimizeConstants - Reorder constant pool for denser encoding.
OptimizeConstants(unsigned CstStart,unsigned CstEnd)520f22ef01cSRoman Divacky void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {
521f22ef01cSRoman Divacky if (CstStart == CstEnd || CstStart+1 == CstEnd) return;
522f22ef01cSRoman Divacky
523ff0cc061SDimitry Andric if (ShouldPreserveUseListOrder)
52439d628a0SDimitry Andric // Optimizing constants makes the use-list order difficult to predict.
52539d628a0SDimitry Andric // Disable it for now when trying to preserve the order.
52639d628a0SDimitry Andric return;
52739d628a0SDimitry Andric
52891bc56edSDimitry Andric std::stable_sort(Values.begin() + CstStart, Values.begin() + CstEnd,
52991bc56edSDimitry Andric [this](const std::pair<const Value *, unsigned> &LHS,
53091bc56edSDimitry Andric const std::pair<const Value *, unsigned> &RHS) {
53191bc56edSDimitry Andric // Sort by plane.
53291bc56edSDimitry Andric if (LHS.first->getType() != RHS.first->getType())
53391bc56edSDimitry Andric return getTypeID(LHS.first->getType()) < getTypeID(RHS.first->getType());
53491bc56edSDimitry Andric // Then by frequency.
53591bc56edSDimitry Andric return LHS.second > RHS.second;
53691bc56edSDimitry Andric });
537f22ef01cSRoman Divacky
538139f7f9bSDimitry Andric // Ensure that integer and vector of integer constants are at the start of the
539139f7f9bSDimitry Andric // constant pool. This is important so that GEP structure indices come before
540139f7f9bSDimitry Andric // gep constant exprs.
5413ca95b02SDimitry Andric std::stable_partition(Values.begin() + CstStart, Values.begin() + CstEnd,
542139f7f9bSDimitry Andric isIntOrIntVectorValue);
543f22ef01cSRoman Divacky
544f22ef01cSRoman Divacky // Rebuild the modified portion of ValueMap.
545f22ef01cSRoman Divacky for (; CstStart != CstEnd; ++CstStart)
546f22ef01cSRoman Divacky ValueMap[Values[CstStart].first] = CstStart+1;
547f22ef01cSRoman Divacky }
548f22ef01cSRoman Divacky
549f22ef01cSRoman Divacky /// EnumerateValueSymbolTable - Insert all of the values in the specified symbol
550f22ef01cSRoman Divacky /// table into the values table.
EnumerateValueSymbolTable(const ValueSymbolTable & VST)551f22ef01cSRoman Divacky void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) {
552f22ef01cSRoman Divacky for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end();
553f22ef01cSRoman Divacky VI != VE; ++VI)
554f22ef01cSRoman Divacky EnumerateValue(VI->getValue());
555f22ef01cSRoman Divacky }
556f22ef01cSRoman Divacky
55739d628a0SDimitry Andric /// Insert all of the values referenced by named metadata in the specified
55839d628a0SDimitry Andric /// module.
EnumerateNamedMetadata(const Module & M)55939d628a0SDimitry Andric void ValueEnumerator::EnumerateNamedMetadata(const Module &M) {
5607d523365SDimitry Andric for (const auto &I : M.named_metadata())
5617d523365SDimitry Andric EnumerateNamedMDNode(&I);
562f22ef01cSRoman Divacky }
563f22ef01cSRoman Divacky
EnumerateNamedMDNode(const NamedMDNode * MD)564f22ef01cSRoman Divacky void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
565e580952dSDimitry Andric for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
5663ca95b02SDimitry Andric EnumerateMetadata(nullptr, MD->getOperand(i));
567f22ef01cSRoman Divacky }
568f22ef01cSRoman Divacky
getMetadataFunctionID(const Function * F) const5693ca95b02SDimitry Andric unsigned ValueEnumerator::getMetadataFunctionID(const Function *F) const {
5703ca95b02SDimitry Andric return F ? getValueID(F) + 1 : 0;
5713ca95b02SDimitry Andric }
5723ca95b02SDimitry Andric
EnumerateMetadata(const Function * F,const Metadata * MD)5733ca95b02SDimitry Andric void ValueEnumerator::EnumerateMetadata(const Function *F, const Metadata *MD) {
5743ca95b02SDimitry Andric EnumerateMetadata(getMetadataFunctionID(F), MD);
5753ca95b02SDimitry Andric }
5763ca95b02SDimitry Andric
EnumerateFunctionLocalMetadata(const Function & F,const LocalAsMetadata * Local)5773ca95b02SDimitry Andric void ValueEnumerator::EnumerateFunctionLocalMetadata(
5783ca95b02SDimitry Andric const Function &F, const LocalAsMetadata *Local) {
5793ca95b02SDimitry Andric EnumerateFunctionLocalMetadata(getMetadataFunctionID(&F), Local);
5803ca95b02SDimitry Andric }
5813ca95b02SDimitry Andric
dropFunctionFromMetadata(MetadataMapType::value_type & FirstMD)5823ca95b02SDimitry Andric void ValueEnumerator::dropFunctionFromMetadata(
5833ca95b02SDimitry Andric MetadataMapType::value_type &FirstMD) {
5843ca95b02SDimitry Andric SmallVector<const MDNode *, 64> Worklist;
5857a7e6055SDimitry Andric auto push = [&Worklist](MetadataMapType::value_type &MD) {
5863ca95b02SDimitry Andric auto &Entry = MD.second;
5873ca95b02SDimitry Andric
5883ca95b02SDimitry Andric // Nothing to do if this metadata isn't tagged.
5893ca95b02SDimitry Andric if (!Entry.F)
5903ca95b02SDimitry Andric return;
5913ca95b02SDimitry Andric
5923ca95b02SDimitry Andric // Drop the function tag.
5933ca95b02SDimitry Andric Entry.F = 0;
5943ca95b02SDimitry Andric
5953ca95b02SDimitry Andric // If this is has an ID and is an MDNode, then its operands have entries as
5963ca95b02SDimitry Andric // well. We need to drop the function from them too.
5973ca95b02SDimitry Andric if (Entry.ID)
5983ca95b02SDimitry Andric if (auto *N = dyn_cast<MDNode>(MD.first))
5993ca95b02SDimitry Andric Worklist.push_back(N);
6003ca95b02SDimitry Andric };
6013ca95b02SDimitry Andric push(FirstMD);
6023ca95b02SDimitry Andric while (!Worklist.empty())
6033ca95b02SDimitry Andric for (const Metadata *Op : Worklist.pop_back_val()->operands()) {
6043ca95b02SDimitry Andric if (!Op)
60539d628a0SDimitry Andric continue;
6063ca95b02SDimitry Andric auto MD = MetadataMap.find(Op);
6073ca95b02SDimitry Andric if (MD != MetadataMap.end())
6083ca95b02SDimitry Andric push(*MD);
609e580952dSDimitry Andric }
610f22ef01cSRoman Divacky }
611f22ef01cSRoman Divacky
EnumerateMetadata(unsigned F,const Metadata * MD)6123ca95b02SDimitry Andric void ValueEnumerator::EnumerateMetadata(unsigned F, const Metadata *MD) {
6133ca95b02SDimitry Andric // It's vital for reader efficiency that uniqued subgraphs are done in
6143ca95b02SDimitry Andric // post-order; it's expensive when their operands have forward references.
6153ca95b02SDimitry Andric // If a distinct node is referenced from a uniqued node, it'll be delayed
6163ca95b02SDimitry Andric // until the uniqued subgraph has been completely traversed.
6173ca95b02SDimitry Andric SmallVector<const MDNode *, 32> DelayedDistinctNodes;
6183ca95b02SDimitry Andric
6193ca95b02SDimitry Andric // Start by enumerating MD, and then work through its transitive operands in
6203ca95b02SDimitry Andric // post-order. This requires a depth-first search.
6213ca95b02SDimitry Andric SmallVector<std::pair<const MDNode *, MDNode::op_iterator>, 32> Worklist;
6223ca95b02SDimitry Andric if (const MDNode *N = enumerateMetadataImpl(F, MD))
6233ca95b02SDimitry Andric Worklist.push_back(std::make_pair(N, N->op_begin()));
6243ca95b02SDimitry Andric
6253ca95b02SDimitry Andric while (!Worklist.empty()) {
6263ca95b02SDimitry Andric const MDNode *N = Worklist.back().first;
6273ca95b02SDimitry Andric
6283ca95b02SDimitry Andric // Enumerate operands until we hit a new node. We need to traverse these
6293ca95b02SDimitry Andric // nodes' operands before visiting the rest of N's operands.
6303ca95b02SDimitry Andric MDNode::op_iterator I = std::find_if(
6313ca95b02SDimitry Andric Worklist.back().second, N->op_end(),
6323ca95b02SDimitry Andric [&](const Metadata *MD) { return enumerateMetadataImpl(F, MD); });
6333ca95b02SDimitry Andric if (I != N->op_end()) {
6343ca95b02SDimitry Andric auto *Op = cast<MDNode>(*I);
6353ca95b02SDimitry Andric Worklist.back().second = ++I;
6363ca95b02SDimitry Andric
6373ca95b02SDimitry Andric // Delay traversing Op if it's a distinct node and N is uniqued.
6383ca95b02SDimitry Andric if (Op->isDistinct() && !N->isDistinct())
6393ca95b02SDimitry Andric DelayedDistinctNodes.push_back(Op);
6403ca95b02SDimitry Andric else
6413ca95b02SDimitry Andric Worklist.push_back(std::make_pair(Op, Op->op_begin()));
6423ca95b02SDimitry Andric continue;
6433ca95b02SDimitry Andric }
6443ca95b02SDimitry Andric
6453ca95b02SDimitry Andric // All the operands have been visited. Now assign an ID.
6463ca95b02SDimitry Andric Worklist.pop_back();
6473ca95b02SDimitry Andric MDs.push_back(N);
6483ca95b02SDimitry Andric MetadataMap[N].ID = MDs.size();
6493ca95b02SDimitry Andric
6503ca95b02SDimitry Andric // Flush out any delayed distinct nodes; these are all the distinct nodes
6513ca95b02SDimitry Andric // that are leaves in last uniqued subgraph.
6523ca95b02SDimitry Andric if (Worklist.empty() || Worklist.back().first->isDistinct()) {
6533ca95b02SDimitry Andric for (const MDNode *N : DelayedDistinctNodes)
6543ca95b02SDimitry Andric Worklist.push_back(std::make_pair(N, N->op_begin()));
6553ca95b02SDimitry Andric DelayedDistinctNodes.clear();
6563ca95b02SDimitry Andric }
6573ca95b02SDimitry Andric }
6583ca95b02SDimitry Andric }
6593ca95b02SDimitry Andric
enumerateMetadataImpl(unsigned F,const Metadata * MD)6603ca95b02SDimitry Andric const MDNode *ValueEnumerator::enumerateMetadataImpl(unsigned F, const Metadata *MD) {
6613ca95b02SDimitry Andric if (!MD)
6623ca95b02SDimitry Andric return nullptr;
6633ca95b02SDimitry Andric
66439d628a0SDimitry Andric assert(
66539d628a0SDimitry Andric (isa<MDNode>(MD) || isa<MDString>(MD) || isa<ConstantAsMetadata>(MD)) &&
66639d628a0SDimitry Andric "Invalid metadata kind");
667e580952dSDimitry Andric
6683ca95b02SDimitry Andric auto Insertion = MetadataMap.insert(std::make_pair(MD, MDIndex(F)));
6693ca95b02SDimitry Andric MDIndex &Entry = Insertion.first->second;
6703ca95b02SDimitry Andric if (!Insertion.second) {
6713ca95b02SDimitry Andric // Already mapped. If F doesn't match the function tag, drop it.
6723ca95b02SDimitry Andric if (Entry.hasDifferentFunction(F))
6733ca95b02SDimitry Andric dropFunctionFromMetadata(*Insertion.first);
6743ca95b02SDimitry Andric return nullptr;
6753ca95b02SDimitry Andric }
676e580952dSDimitry Andric
6773ca95b02SDimitry Andric // Don't assign IDs to metadata nodes.
67839d628a0SDimitry Andric if (auto *N = dyn_cast<MDNode>(MD))
6793ca95b02SDimitry Andric return N;
6803ca95b02SDimitry Andric
6813ca95b02SDimitry Andric // Save the metadata.
6823ca95b02SDimitry Andric MDs.push_back(MD);
6833ca95b02SDimitry Andric Entry.ID = MDs.size();
6843ca95b02SDimitry Andric
6853ca95b02SDimitry Andric // Enumerate the constant, if any.
6863ca95b02SDimitry Andric if (auto *C = dyn_cast<ConstantAsMetadata>(MD))
68739d628a0SDimitry Andric EnumerateValue(C->getValue());
68839d628a0SDimitry Andric
6893ca95b02SDimitry Andric return nullptr;
690e580952dSDimitry Andric }
691e580952dSDimitry Andric
692e580952dSDimitry Andric /// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata
69339d628a0SDimitry Andric /// information reachable from the metadata.
EnumerateFunctionLocalMetadata(unsigned F,const LocalAsMetadata * Local)69439d628a0SDimitry Andric void ValueEnumerator::EnumerateFunctionLocalMetadata(
6953ca95b02SDimitry Andric unsigned F, const LocalAsMetadata *Local) {
6963ca95b02SDimitry Andric assert(F && "Expected a function");
6973ca95b02SDimitry Andric
698e580952dSDimitry Andric // Check to see if it's already in!
6993ca95b02SDimitry Andric MDIndex &Index = MetadataMap[Local];
7003ca95b02SDimitry Andric if (Index.ID) {
7013ca95b02SDimitry Andric assert(Index.F == F && "Expected the same function");
702f22ef01cSRoman Divacky return;
7033ca95b02SDimitry Andric }
704e580952dSDimitry Andric
70539d628a0SDimitry Andric MDs.push_back(Local);
7063ca95b02SDimitry Andric Index.F = F;
7073ca95b02SDimitry Andric Index.ID = MDs.size();
708e580952dSDimitry Andric
70939d628a0SDimitry Andric EnumerateValue(Local->getValue());
7103ca95b02SDimitry Andric }
71139d628a0SDimitry Andric
getMetadataTypeOrder(const Metadata * MD)7123ca95b02SDimitry Andric static unsigned getMetadataTypeOrder(const Metadata *MD) {
7133ca95b02SDimitry Andric // Strings are emitted in bulk and must come first.
7143ca95b02SDimitry Andric if (isa<MDString>(MD))
7153ca95b02SDimitry Andric return 0;
7163ca95b02SDimitry Andric
7173ca95b02SDimitry Andric // ConstantAsMetadata doesn't reference anything. We may as well shuffle it
7183ca95b02SDimitry Andric // to the front since we can detect it.
7193ca95b02SDimitry Andric auto *N = dyn_cast<MDNode>(MD);
7203ca95b02SDimitry Andric if (!N)
7213ca95b02SDimitry Andric return 1;
7223ca95b02SDimitry Andric
7233ca95b02SDimitry Andric // The reader is fast forward references for distinct node operands, but slow
7243ca95b02SDimitry Andric // when uniqued operands are unresolved.
7253ca95b02SDimitry Andric return N->isDistinct() ? 2 : 3;
7263ca95b02SDimitry Andric }
7273ca95b02SDimitry Andric
organizeMetadata()7283ca95b02SDimitry Andric void ValueEnumerator::organizeMetadata() {
7293ca95b02SDimitry Andric assert(MetadataMap.size() == MDs.size() &&
7303ca95b02SDimitry Andric "Metadata map and vector out of sync");
7313ca95b02SDimitry Andric
7323ca95b02SDimitry Andric if (MDs.empty())
7333ca95b02SDimitry Andric return;
7343ca95b02SDimitry Andric
7353ca95b02SDimitry Andric // Copy out the index information from MetadataMap in order to choose a new
7363ca95b02SDimitry Andric // order.
7373ca95b02SDimitry Andric SmallVector<MDIndex, 64> Order;
7383ca95b02SDimitry Andric Order.reserve(MetadataMap.size());
7393ca95b02SDimitry Andric for (const Metadata *MD : MDs)
7403ca95b02SDimitry Andric Order.push_back(MetadataMap.lookup(MD));
7413ca95b02SDimitry Andric
7423ca95b02SDimitry Andric // Partition:
7433ca95b02SDimitry Andric // - by function, then
7443ca95b02SDimitry Andric // - by isa<MDString>
7453ca95b02SDimitry Andric // and then sort by the original/current ID. Since the IDs are guaranteed to
7463ca95b02SDimitry Andric // be unique, the result of std::sort will be deterministic. There's no need
7473ca95b02SDimitry Andric // for std::stable_sort.
748*b5893f02SDimitry Andric llvm::sort(Order, [this](MDIndex LHS, MDIndex RHS) {
7493ca95b02SDimitry Andric return std::make_tuple(LHS.F, getMetadataTypeOrder(LHS.get(MDs)), LHS.ID) <
7503ca95b02SDimitry Andric std::make_tuple(RHS.F, getMetadataTypeOrder(RHS.get(MDs)), RHS.ID);
7513ca95b02SDimitry Andric });
7523ca95b02SDimitry Andric
7533ca95b02SDimitry Andric // Rebuild MDs, index the metadata ranges for each function in FunctionMDs,
7543ca95b02SDimitry Andric // and fix up MetadataMap.
7553ca95b02SDimitry Andric std::vector<const Metadata *> OldMDs = std::move(MDs);
7563ca95b02SDimitry Andric MDs.reserve(OldMDs.size());
7573ca95b02SDimitry Andric for (unsigned I = 0, E = Order.size(); I != E && !Order[I].F; ++I) {
7583ca95b02SDimitry Andric auto *MD = Order[I].get(OldMDs);
7593ca95b02SDimitry Andric MDs.push_back(MD);
7603ca95b02SDimitry Andric MetadataMap[MD].ID = I + 1;
7613ca95b02SDimitry Andric if (isa<MDString>(MD))
7623ca95b02SDimitry Andric ++NumMDStrings;
7633ca95b02SDimitry Andric }
7643ca95b02SDimitry Andric
7653ca95b02SDimitry Andric // Return early if there's nothing for the functions.
7663ca95b02SDimitry Andric if (MDs.size() == Order.size())
7673ca95b02SDimitry Andric return;
7683ca95b02SDimitry Andric
7693ca95b02SDimitry Andric // Build the function metadata ranges.
7703ca95b02SDimitry Andric MDRange R;
7713ca95b02SDimitry Andric FunctionMDs.reserve(OldMDs.size());
7723ca95b02SDimitry Andric unsigned PrevF = 0;
7733ca95b02SDimitry Andric for (unsigned I = MDs.size(), E = Order.size(), ID = MDs.size(); I != E;
7743ca95b02SDimitry Andric ++I) {
7753ca95b02SDimitry Andric unsigned F = Order[I].F;
7763ca95b02SDimitry Andric if (!PrevF) {
7773ca95b02SDimitry Andric PrevF = F;
7783ca95b02SDimitry Andric } else if (PrevF != F) {
7793ca95b02SDimitry Andric R.Last = FunctionMDs.size();
7803ca95b02SDimitry Andric std::swap(R, FunctionMDInfo[PrevF]);
7813ca95b02SDimitry Andric R.First = FunctionMDs.size();
7823ca95b02SDimitry Andric
7833ca95b02SDimitry Andric ID = MDs.size();
7843ca95b02SDimitry Andric PrevF = F;
7853ca95b02SDimitry Andric }
7863ca95b02SDimitry Andric
7873ca95b02SDimitry Andric auto *MD = Order[I].get(OldMDs);
7883ca95b02SDimitry Andric FunctionMDs.push_back(MD);
7893ca95b02SDimitry Andric MetadataMap[MD].ID = ++ID;
7903ca95b02SDimitry Andric if (isa<MDString>(MD))
7913ca95b02SDimitry Andric ++R.NumStrings;
7923ca95b02SDimitry Andric }
7933ca95b02SDimitry Andric R.Last = FunctionMDs.size();
7943ca95b02SDimitry Andric FunctionMDInfo[PrevF] = R;
7953ca95b02SDimitry Andric }
7963ca95b02SDimitry Andric
incorporateFunctionMetadata(const Function & F)7973ca95b02SDimitry Andric void ValueEnumerator::incorporateFunctionMetadata(const Function &F) {
7983ca95b02SDimitry Andric NumModuleMDs = MDs.size();
7993ca95b02SDimitry Andric
8003ca95b02SDimitry Andric auto R = FunctionMDInfo.lookup(getValueID(&F) + 1);
8013ca95b02SDimitry Andric NumMDStrings = R.NumStrings;
8023ca95b02SDimitry Andric MDs.insert(MDs.end(), FunctionMDs.begin() + R.First,
8033ca95b02SDimitry Andric FunctionMDs.begin() + R.Last);
804f22ef01cSRoman Divacky }
805f22ef01cSRoman Divacky
EnumerateValue(const Value * V)806f22ef01cSRoman Divacky void ValueEnumerator::EnumerateValue(const Value *V) {
807f22ef01cSRoman Divacky assert(!V->getType()->isVoidTy() && "Can't insert void values!");
80839d628a0SDimitry Andric assert(!isa<MetadataAsValue>(V) && "EnumerateValue doesn't handle Metadata!");
809f22ef01cSRoman Divacky
810f22ef01cSRoman Divacky // Check to see if it's already in!
811f22ef01cSRoman Divacky unsigned &ValueID = ValueMap[V];
812f22ef01cSRoman Divacky if (ValueID) {
813f22ef01cSRoman Divacky // Increment use count.
814f22ef01cSRoman Divacky Values[ValueID-1].second++;
815f22ef01cSRoman Divacky return;
816f22ef01cSRoman Divacky }
817f22ef01cSRoman Divacky
81891bc56edSDimitry Andric if (auto *GO = dyn_cast<GlobalObject>(V))
81991bc56edSDimitry Andric if (const Comdat *C = GO->getComdat())
82091bc56edSDimitry Andric Comdats.insert(C);
82191bc56edSDimitry Andric
822f22ef01cSRoman Divacky // Enumerate the type of this value.
823f22ef01cSRoman Divacky EnumerateType(V->getType());
824f22ef01cSRoman Divacky
825f22ef01cSRoman Divacky if (const Constant *C = dyn_cast<Constant>(V)) {
826f22ef01cSRoman Divacky if (isa<GlobalValue>(C)) {
827f22ef01cSRoman Divacky // Initializers for globals are handled explicitly elsewhere.
828f22ef01cSRoman Divacky } else if (C->getNumOperands()) {
829f22ef01cSRoman Divacky // If a constant has operands, enumerate them. This makes sure that if a
830f22ef01cSRoman Divacky // constant has uses (for example an array of const ints), that they are
831f22ef01cSRoman Divacky // inserted also.
832f22ef01cSRoman Divacky
833f22ef01cSRoman Divacky // We prefer to enumerate them with values before we enumerate the user
834f22ef01cSRoman Divacky // itself. This makes it more likely that we can avoid forward references
835f22ef01cSRoman Divacky // in the reader. We know that there can be no cycles in the constants
836f22ef01cSRoman Divacky // graph that don't go through a global variable.
837f22ef01cSRoman Divacky for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
838f22ef01cSRoman Divacky I != E; ++I)
839f22ef01cSRoman Divacky if (!isa<BasicBlock>(*I)) // Don't enumerate BB operand to BlockAddress.
840f22ef01cSRoman Divacky EnumerateValue(*I);
841f22ef01cSRoman Divacky
842f22ef01cSRoman Divacky // Finally, add the value. Doing this could make the ValueID reference be
843f22ef01cSRoman Divacky // dangling, don't reuse it.
844f22ef01cSRoman Divacky Values.push_back(std::make_pair(V, 1U));
845f22ef01cSRoman Divacky ValueMap[V] = Values.size();
846f22ef01cSRoman Divacky return;
847f22ef01cSRoman Divacky }
848f22ef01cSRoman Divacky }
849f22ef01cSRoman Divacky
850f22ef01cSRoman Divacky // Add the value.
851f22ef01cSRoman Divacky Values.push_back(std::make_pair(V, 1U));
852f22ef01cSRoman Divacky ValueID = Values.size();
853f22ef01cSRoman Divacky }
854f22ef01cSRoman Divacky
855f22ef01cSRoman Divacky
EnumerateType(Type * Ty)8566122f3e6SDimitry Andric void ValueEnumerator::EnumerateType(Type *Ty) {
85717a519f9SDimitry Andric unsigned *TypeID = &TypeMap[Ty];
858f22ef01cSRoman Divacky
8593b0f4066SDimitry Andric // We've already seen this type.
86017a519f9SDimitry Andric if (*TypeID)
861f22ef01cSRoman Divacky return;
862f22ef01cSRoman Divacky
86317a519f9SDimitry Andric // If it is a non-anonymous struct, mark the type as being visited so that we
86417a519f9SDimitry Andric // don't recursively visit it. This is safe because we allow forward
86517a519f9SDimitry Andric // references of these in the bitcode reader.
8666122f3e6SDimitry Andric if (StructType *STy = dyn_cast<StructType>(Ty))
8676122f3e6SDimitry Andric if (!STy->isLiteral())
86817a519f9SDimitry Andric *TypeID = ~0U;
869f22ef01cSRoman Divacky
87017a519f9SDimitry Andric // Enumerate all of the subtypes before we enumerate this type. This ensures
87117a519f9SDimitry Andric // that the type will be enumerated in an order that can be directly built.
87239d628a0SDimitry Andric for (Type *SubTy : Ty->subtypes())
87339d628a0SDimitry Andric EnumerateType(SubTy);
87417a519f9SDimitry Andric
87517a519f9SDimitry Andric // Refresh the TypeID pointer in case the table rehashed.
87617a519f9SDimitry Andric TypeID = &TypeMap[Ty];
87717a519f9SDimitry Andric
87817a519f9SDimitry Andric // Check to see if we got the pointer another way. This can happen when
87917a519f9SDimitry Andric // enumerating recursive types that hit the base case deeper than they start.
88017a519f9SDimitry Andric //
88117a519f9SDimitry Andric // If this is actually a struct that we are treating as forward ref'able,
88217a519f9SDimitry Andric // then emit the definition now that all of its contents are available.
88317a519f9SDimitry Andric if (*TypeID && *TypeID != ~0U)
88417a519f9SDimitry Andric return;
88517a519f9SDimitry Andric
88617a519f9SDimitry Andric // Add this type now that its contents are all happily enumerated.
88717a519f9SDimitry Andric Types.push_back(Ty);
88817a519f9SDimitry Andric
88917a519f9SDimitry Andric *TypeID = Types.size();
890f22ef01cSRoman Divacky }
891f22ef01cSRoman Divacky
892f22ef01cSRoman Divacky // Enumerate the types for the specified value. If the value is a constant,
893f22ef01cSRoman Divacky // walk through it, enumerating the types of the constant.
EnumerateOperandType(const Value * V)894f22ef01cSRoman Divacky void ValueEnumerator::EnumerateOperandType(const Value *V) {
895f22ef01cSRoman Divacky EnumerateType(V->getType());
896f22ef01cSRoman Divacky
8973ca95b02SDimitry Andric assert(!isa<MetadataAsValue>(V) && "Unexpected metadata operand");
89839d628a0SDimitry Andric
89939d628a0SDimitry Andric const Constant *C = dyn_cast<Constant>(V);
90039d628a0SDimitry Andric if (!C)
90139d628a0SDimitry Andric return;
90239d628a0SDimitry Andric
903f22ef01cSRoman Divacky // If this constant is already enumerated, ignore it, we know its type must
904f22ef01cSRoman Divacky // be enumerated.
90539d628a0SDimitry Andric if (ValueMap.count(C))
90639d628a0SDimitry Andric return;
907f22ef01cSRoman Divacky
908f22ef01cSRoman Divacky // This constant may have operands, make sure to enumerate the types in
909f22ef01cSRoman Divacky // them.
9103dac3a9bSDimitry Andric for (const Value *Op : C->operands()) {
911f22ef01cSRoman Divacky // Don't enumerate basic blocks here, this happens as operands to
912f22ef01cSRoman Divacky // blockaddress.
91339d628a0SDimitry Andric if (isa<BasicBlock>(Op))
91439d628a0SDimitry Andric continue;
915f22ef01cSRoman Divacky
916e580952dSDimitry Andric EnumerateOperandType(Op);
917f22ef01cSRoman Divacky }
918f22ef01cSRoman Divacky }
919f22ef01cSRoman Divacky
EnumerateAttributes(AttributeList PAL)9207a7e6055SDimitry Andric void ValueEnumerator::EnumerateAttributes(AttributeList PAL) {
921f22ef01cSRoman Divacky if (PAL.isEmpty()) return; // null is always 0.
922139f7f9bSDimitry Andric
923f22ef01cSRoman Divacky // Do a lookup.
92451690af2SDimitry Andric unsigned &Entry = AttributeListMap[PAL];
925f22ef01cSRoman Divacky if (Entry == 0) {
926f22ef01cSRoman Divacky // Never saw this before, add it.
92751690af2SDimitry Andric AttributeLists.push_back(PAL);
92851690af2SDimitry Andric Entry = AttributeLists.size();
929139f7f9bSDimitry Andric }
930139f7f9bSDimitry Andric
931139f7f9bSDimitry Andric // Do lookups for all attribute groups.
932302affcbSDimitry Andric for (unsigned i = PAL.index_begin(), e = PAL.index_end(); i != e; ++i) {
933302affcbSDimitry Andric AttributeSet AS = PAL.getAttributes(i);
934302affcbSDimitry Andric if (!AS.hasAttributes())
935302affcbSDimitry Andric continue;
936302affcbSDimitry Andric IndexAndAttrSet Pair = {i, AS};
93751690af2SDimitry Andric unsigned &Entry = AttributeGroupMap[Pair];
938139f7f9bSDimitry Andric if (Entry == 0) {
93951690af2SDimitry Andric AttributeGroups.push_back(Pair);
940139f7f9bSDimitry Andric Entry = AttributeGroups.size();
941139f7f9bSDimitry Andric }
942f22ef01cSRoman Divacky }
943f22ef01cSRoman Divacky }
944f22ef01cSRoman Divacky
incorporateFunction(const Function & F)945f22ef01cSRoman Divacky void ValueEnumerator::incorporateFunction(const Function &F) {
946f22ef01cSRoman Divacky InstructionCount = 0;
947f22ef01cSRoman Divacky NumModuleValues = Values.size();
9483ca95b02SDimitry Andric
9493ca95b02SDimitry Andric // Add global metadata to the function block. This doesn't include
9503ca95b02SDimitry Andric // LocalAsMetadata.
9513ca95b02SDimitry Andric incorporateFunctionMetadata(F);
952f22ef01cSRoman Divacky
953f22ef01cSRoman Divacky // Adding function arguments to the value table.
9547d523365SDimitry Andric for (const auto &I : F.args())
9557d523365SDimitry Andric EnumerateValue(&I);
956f22ef01cSRoman Divacky
957f22ef01cSRoman Divacky FirstFuncConstantID = Values.size();
958f22ef01cSRoman Divacky
959f22ef01cSRoman Divacky // Add all function-level constants to the value table.
9607d523365SDimitry Andric for (const BasicBlock &BB : F) {
9617d523365SDimitry Andric for (const Instruction &I : BB)
9627d523365SDimitry Andric for (const Use &OI : I.operands()) {
9637d523365SDimitry Andric if ((isa<Constant>(OI) && !isa<GlobalValue>(OI)) || isa<InlineAsm>(OI))
9647d523365SDimitry Andric EnumerateValue(OI);
965f22ef01cSRoman Divacky }
9667d523365SDimitry Andric BasicBlocks.push_back(&BB);
9677d523365SDimitry Andric ValueMap[&BB] = BasicBlocks.size();
968f22ef01cSRoman Divacky }
969f22ef01cSRoman Divacky
970f22ef01cSRoman Divacky // Optimize the constant layout.
971f22ef01cSRoman Divacky OptimizeConstants(FirstFuncConstantID, Values.size());
972f22ef01cSRoman Divacky
973f22ef01cSRoman Divacky // Add the function's parameter attributes so they are available for use in
974f22ef01cSRoman Divacky // the function's instruction.
975f22ef01cSRoman Divacky EnumerateAttributes(F.getAttributes());
976f22ef01cSRoman Divacky
977f22ef01cSRoman Divacky FirstInstID = Values.size();
978f22ef01cSRoman Divacky
97939d628a0SDimitry Andric SmallVector<LocalAsMetadata *, 8> FnLocalMDVector;
980f22ef01cSRoman Divacky // Add all of the instructions.
9817d523365SDimitry Andric for (const BasicBlock &BB : F) {
9827d523365SDimitry Andric for (const Instruction &I : BB) {
9837d523365SDimitry Andric for (const Use &OI : I.operands()) {
9847d523365SDimitry Andric if (auto *MD = dyn_cast<MetadataAsValue>(&OI))
98539d628a0SDimitry Andric if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata()))
986f22ef01cSRoman Divacky // Enumerate metadata after the instructions they might refer to.
98739d628a0SDimitry Andric FnLocalMDVector.push_back(Local);
988e580952dSDimitry Andric }
989e580952dSDimitry Andric
9907d523365SDimitry Andric if (!I.getType()->isVoidTy())
9917d523365SDimitry Andric EnumerateValue(&I);
992f22ef01cSRoman Divacky }
993f22ef01cSRoman Divacky }
994f22ef01cSRoman Divacky
995f22ef01cSRoman Divacky // Add all of the function-local metadata.
9963ca95b02SDimitry Andric for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i) {
9973ca95b02SDimitry Andric // At this point, every local values have been incorporated, we shouldn't
9983ca95b02SDimitry Andric // have a metadata operand that references a value that hasn't been seen.
9993ca95b02SDimitry Andric assert(ValueMap.count(FnLocalMDVector[i]->getValue()) &&
10003ca95b02SDimitry Andric "Missing value for metadata operand");
10013ca95b02SDimitry Andric EnumerateFunctionLocalMetadata(F, FnLocalMDVector[i]);
10023ca95b02SDimitry Andric }
1003f22ef01cSRoman Divacky }
1004f22ef01cSRoman Divacky
purgeFunction()1005f22ef01cSRoman Divacky void ValueEnumerator::purgeFunction() {
1006f22ef01cSRoman Divacky /// Remove purged values from the ValueMap.
1007f22ef01cSRoman Divacky for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i)
1008f22ef01cSRoman Divacky ValueMap.erase(Values[i].first);
100939d628a0SDimitry Andric for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i)
10107d523365SDimitry Andric MetadataMap.erase(MDs[i]);
1011f22ef01cSRoman Divacky for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
1012f22ef01cSRoman Divacky ValueMap.erase(BasicBlocks[i]);
1013f22ef01cSRoman Divacky
1014f22ef01cSRoman Divacky Values.resize(NumModuleValues);
101539d628a0SDimitry Andric MDs.resize(NumModuleMDs);
1016f22ef01cSRoman Divacky BasicBlocks.clear();
10173ca95b02SDimitry Andric NumMDStrings = 0;
1018f22ef01cSRoman Divacky }
1019f22ef01cSRoman Divacky
IncorporateFunctionInfoGlobalBBIDs(const Function * F,DenseMap<const BasicBlock *,unsigned> & IDMap)1020f22ef01cSRoman Divacky static void IncorporateFunctionInfoGlobalBBIDs(const Function *F,
1021f22ef01cSRoman Divacky DenseMap<const BasicBlock*, unsigned> &IDMap) {
1022f22ef01cSRoman Divacky unsigned Counter = 0;
10237d523365SDimitry Andric for (const BasicBlock &BB : *F)
10247d523365SDimitry Andric IDMap[&BB] = ++Counter;
1025f22ef01cSRoman Divacky }
1026f22ef01cSRoman Divacky
1027f22ef01cSRoman Divacky /// getGlobalBasicBlockID - This returns the function-specific ID for the
1028f22ef01cSRoman Divacky /// specified basic block. This is relatively expensive information, so it
1029f22ef01cSRoman Divacky /// should only be used by rare constructs such as address-of-label.
getGlobalBasicBlockID(const BasicBlock * BB) const1030f22ef01cSRoman Divacky unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const {
1031f22ef01cSRoman Divacky unsigned &Idx = GlobalBasicBlockIDs[BB];
1032f22ef01cSRoman Divacky if (Idx != 0)
1033f22ef01cSRoman Divacky return Idx-1;
1034f22ef01cSRoman Divacky
1035f22ef01cSRoman Divacky IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs);
1036f22ef01cSRoman Divacky return getGlobalBasicBlockID(BB);
1037f22ef01cSRoman Divacky }
1038ff0cc061SDimitry Andric
computeBitsRequiredForTypeIndicies() const1039ff0cc061SDimitry Andric uint64_t ValueEnumerator::computeBitsRequiredForTypeIndicies() const {
1040ff0cc061SDimitry Andric return Log2_32_Ceil(getTypes().size() + 1);
1041ff0cc061SDimitry Andric }
1042