171db6425SDuncan P. N. Exon Smith //===- Metadata.cpp - Implement Metadata classes --------------------------===//
2ef860a24SChandler Carruth //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ef860a24SChandler Carruth //
7ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
8ef860a24SChandler Carruth //
9ef860a24SChandler Carruth // This file implements the Metadata classes.
10ef860a24SChandler Carruth //
11ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
12ef860a24SChandler Carruth
13ca2e7e59SFlorian Hahn #include "llvm/IR/Metadata.h"
14ef860a24SChandler Carruth #include "LLVMContextImpl.h"
15d9901ff5SDuncan P. N. Exon Smith #include "MetadataImpl.h"
16deaf6951SEugene Zelenko #include "llvm/ADT/APFloat.h"
17deaf6951SEugene Zelenko #include "llvm/ADT/APInt.h"
18deaf6951SEugene Zelenko #include "llvm/ADT/ArrayRef.h"
19deaf6951SEugene Zelenko #include "llvm/ADT/DenseSet.h"
20deaf6951SEugene Zelenko #include "llvm/ADT/None.h"
216bda14b3SChandler Carruth #include "llvm/ADT/STLExtras.h"
22fa0f1e66SDavid Majnemer #include "llvm/ADT/SetVector.h"
23deaf6951SEugene Zelenko #include "llvm/ADT/SmallPtrSet.h"
24ab73c493SRafael Espindola #include "llvm/ADT/SmallSet.h"
25deaf6951SEugene Zelenko #include "llvm/ADT/SmallVector.h"
26ef860a24SChandler Carruth #include "llvm/ADT/StringMap.h"
27deaf6951SEugene Zelenko #include "llvm/ADT/StringRef.h"
28de6cce22SEugene Zelenko #include "llvm/ADT/Twine.h"
29deaf6951SEugene Zelenko #include "llvm/IR/Argument.h"
30deaf6951SEugene Zelenko #include "llvm/IR/BasicBlock.h"
31deaf6951SEugene Zelenko #include "llvm/IR/Constant.h"
328cd041efSChandler Carruth #include "llvm/IR/ConstantRange.h"
33deaf6951SEugene Zelenko #include "llvm/IR/Constants.h"
34d9901ff5SDuncan P. N. Exon Smith #include "llvm/IR/DebugInfoMetadata.h"
35deaf6951SEugene Zelenko #include "llvm/IR/DebugLoc.h"
36deaf6951SEugene Zelenko #include "llvm/IR/Function.h"
37deaf6951SEugene Zelenko #include "llvm/IR/GlobalObject.h"
38deaf6951SEugene Zelenko #include "llvm/IR/GlobalVariable.h"
399fb823bbSChandler Carruth #include "llvm/IR/Instruction.h"
409fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h"
41ca2e7e59SFlorian Hahn #include "llvm/IR/MDBuilder.h"
429fb823bbSChandler Carruth #include "llvm/IR/Module.h"
43deaf6951SEugene Zelenko #include "llvm/IR/TrackingMDRef.h"
44deaf6951SEugene Zelenko #include "llvm/IR/Type.h"
45deaf6951SEugene Zelenko #include "llvm/IR/Value.h"
46deaf6951SEugene Zelenko #include "llvm/Support/Casting.h"
47deaf6951SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
48deaf6951SEugene Zelenko #include "llvm/Support/MathExtras.h"
49deaf6951SEugene Zelenko #include <algorithm>
50deaf6951SEugene Zelenko #include <cassert>
51deaf6951SEugene Zelenko #include <cstddef>
52deaf6951SEugene Zelenko #include <cstdint>
53de6cce22SEugene Zelenko #include <type_traits>
54deaf6951SEugene Zelenko #include <utility>
55deaf6951SEugene Zelenko #include <vector>
5646d91ad4SDuncan P. N. Exon Smith
57ef860a24SChandler Carruth using namespace llvm;
58ef860a24SChandler Carruth
MetadataAsValue(Type * Ty,Metadata * MD)595bf8fef5SDuncan P. N. Exon Smith MetadataAsValue::MetadataAsValue(Type *Ty, Metadata *MD)
605bf8fef5SDuncan P. N. Exon Smith : Value(Ty, MetadataAsValueVal), MD(MD) {
615bf8fef5SDuncan P. N. Exon Smith track();
625bf8fef5SDuncan P. N. Exon Smith }
635bf8fef5SDuncan P. N. Exon Smith
~MetadataAsValue()645bf8fef5SDuncan P. N. Exon Smith MetadataAsValue::~MetadataAsValue() {
655bf8fef5SDuncan P. N. Exon Smith getType()->getContext().pImpl->MetadataAsValues.erase(MD);
665bf8fef5SDuncan P. N. Exon Smith untrack();
675bf8fef5SDuncan P. N. Exon Smith }
685bf8fef5SDuncan P. N. Exon Smith
699da9c766SSanjay Patel /// Canonicalize metadata arguments to intrinsics.
705bf8fef5SDuncan P. N. Exon Smith ///
715bf8fef5SDuncan P. N. Exon Smith /// To support bitcode upgrades (and assembly semantic sugar) for \a
725bf8fef5SDuncan P. N. Exon Smith /// MetadataAsValue, we need to canonicalize certain metadata.
735bf8fef5SDuncan P. N. Exon Smith ///
745bf8fef5SDuncan P. N. Exon Smith /// - nullptr is replaced by an empty MDNode.
755bf8fef5SDuncan P. N. Exon Smith /// - An MDNode with a single null operand is replaced by an empty MDNode.
765bf8fef5SDuncan P. N. Exon Smith /// - An MDNode whose only operand is a \a ConstantAsMetadata gets skipped.
775bf8fef5SDuncan P. N. Exon Smith ///
785bf8fef5SDuncan P. N. Exon Smith /// This maintains readability of bitcode from when metadata was a type of
795bf8fef5SDuncan P. N. Exon Smith /// value, and these bridges were unnecessary.
canonicalizeMetadataForValue(LLVMContext & Context,Metadata * MD)805bf8fef5SDuncan P. N. Exon Smith static Metadata *canonicalizeMetadataForValue(LLVMContext &Context,
815bf8fef5SDuncan P. N. Exon Smith Metadata *MD) {
825bf8fef5SDuncan P. N. Exon Smith if (!MD)
835bf8fef5SDuncan P. N. Exon Smith // !{}
845bf8fef5SDuncan P. N. Exon Smith return MDNode::get(Context, None);
855bf8fef5SDuncan P. N. Exon Smith
865bf8fef5SDuncan P. N. Exon Smith // Return early if this isn't a single-operand MDNode.
875bf8fef5SDuncan P. N. Exon Smith auto *N = dyn_cast<MDNode>(MD);
885bf8fef5SDuncan P. N. Exon Smith if (!N || N->getNumOperands() != 1)
895bf8fef5SDuncan P. N. Exon Smith return MD;
905bf8fef5SDuncan P. N. Exon Smith
915bf8fef5SDuncan P. N. Exon Smith if (!N->getOperand(0))
925bf8fef5SDuncan P. N. Exon Smith // !{}
935bf8fef5SDuncan P. N. Exon Smith return MDNode::get(Context, None);
945bf8fef5SDuncan P. N. Exon Smith
955bf8fef5SDuncan P. N. Exon Smith if (auto *C = dyn_cast<ConstantAsMetadata>(N->getOperand(0)))
965bf8fef5SDuncan P. N. Exon Smith // Look through the MDNode.
975bf8fef5SDuncan P. N. Exon Smith return C;
985bf8fef5SDuncan P. N. Exon Smith
995bf8fef5SDuncan P. N. Exon Smith return MD;
1005bf8fef5SDuncan P. N. Exon Smith }
1015bf8fef5SDuncan P. N. Exon Smith
get(LLVMContext & Context,Metadata * MD)1025bf8fef5SDuncan P. N. Exon Smith MetadataAsValue *MetadataAsValue::get(LLVMContext &Context, Metadata *MD) {
1035bf8fef5SDuncan P. N. Exon Smith MD = canonicalizeMetadataForValue(Context, MD);
1045bf8fef5SDuncan P. N. Exon Smith auto *&Entry = Context.pImpl->MetadataAsValues[MD];
1055bf8fef5SDuncan P. N. Exon Smith if (!Entry)
1065bf8fef5SDuncan P. N. Exon Smith Entry = new MetadataAsValue(Type::getMetadataTy(Context), MD);
1075bf8fef5SDuncan P. N. Exon Smith return Entry;
1085bf8fef5SDuncan P. N. Exon Smith }
1095bf8fef5SDuncan P. N. Exon Smith
getIfExists(LLVMContext & Context,Metadata * MD)1105bf8fef5SDuncan P. N. Exon Smith MetadataAsValue *MetadataAsValue::getIfExists(LLVMContext &Context,
1115bf8fef5SDuncan P. N. Exon Smith Metadata *MD) {
1125bf8fef5SDuncan P. N. Exon Smith MD = canonicalizeMetadataForValue(Context, MD);
1135bf8fef5SDuncan P. N. Exon Smith auto &Store = Context.pImpl->MetadataAsValues;
1144c1f097bSBenjamin Kramer return Store.lookup(MD);
1155bf8fef5SDuncan P. N. Exon Smith }
1165bf8fef5SDuncan P. N. Exon Smith
handleChangedMetadata(Metadata * MD)1175bf8fef5SDuncan P. N. Exon Smith void MetadataAsValue::handleChangedMetadata(Metadata *MD) {
1185bf8fef5SDuncan P. N. Exon Smith LLVMContext &Context = getContext();
1195bf8fef5SDuncan P. N. Exon Smith MD = canonicalizeMetadataForValue(Context, MD);
1205bf8fef5SDuncan P. N. Exon Smith auto &Store = Context.pImpl->MetadataAsValues;
1215bf8fef5SDuncan P. N. Exon Smith
1225bf8fef5SDuncan P. N. Exon Smith // Stop tracking the old metadata.
1235bf8fef5SDuncan P. N. Exon Smith Store.erase(this->MD);
1245bf8fef5SDuncan P. N. Exon Smith untrack();
1255bf8fef5SDuncan P. N. Exon Smith this->MD = nullptr;
1265bf8fef5SDuncan P. N. Exon Smith
1275bf8fef5SDuncan P. N. Exon Smith // Start tracking MD, or RAUW if necessary.
1285bf8fef5SDuncan P. N. Exon Smith auto *&Entry = Store[MD];
1295bf8fef5SDuncan P. N. Exon Smith if (Entry) {
1305bf8fef5SDuncan P. N. Exon Smith replaceAllUsesWith(Entry);
1315bf8fef5SDuncan P. N. Exon Smith delete this;
1325bf8fef5SDuncan P. N. Exon Smith return;
1335bf8fef5SDuncan P. N. Exon Smith }
1345bf8fef5SDuncan P. N. Exon Smith
1355bf8fef5SDuncan P. N. Exon Smith this->MD = MD;
1365bf8fef5SDuncan P. N. Exon Smith track();
1375bf8fef5SDuncan P. N. Exon Smith Entry = this;
1385bf8fef5SDuncan P. N. Exon Smith }
1395bf8fef5SDuncan P. N. Exon Smith
track()1405bf8fef5SDuncan P. N. Exon Smith void MetadataAsValue::track() {
1415bf8fef5SDuncan P. N. Exon Smith if (MD)
1425bf8fef5SDuncan P. N. Exon Smith MetadataTracking::track(&MD, *MD, *this);
1435bf8fef5SDuncan P. N. Exon Smith }
1445bf8fef5SDuncan P. N. Exon Smith
untrack()1455bf8fef5SDuncan P. N. Exon Smith void MetadataAsValue::untrack() {
1465bf8fef5SDuncan P. N. Exon Smith if (MD)
1475bf8fef5SDuncan P. N. Exon Smith MetadataTracking::untrack(MD);
1485bf8fef5SDuncan P. N. Exon Smith }
1495bf8fef5SDuncan P. N. Exon Smith
track(void * Ref,Metadata & MD,OwnerTy Owner)150a7dc087bSChandler Carruth bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) {
151a7dc087bSChandler Carruth assert(Ref && "Expected live reference");
152a7dc087bSChandler Carruth assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
153a7dc087bSChandler Carruth "Reference without owner must be direct");
154fef609f1SDuncan P. N. Exon Smith if (auto *R = ReplaceableMetadataImpl::getOrCreate(MD)) {
155a7dc087bSChandler Carruth R->addRef(Ref, Owner);
156a7dc087bSChandler Carruth return true;
157a7dc087bSChandler Carruth }
1584b1bc647SDuncan P. N. Exon Smith if (auto *PH = dyn_cast<DistinctMDOperandPlaceholder>(&MD)) {
1594b1bc647SDuncan P. N. Exon Smith assert(!PH->Use && "Placeholders can only be used once");
1604b1bc647SDuncan P. N. Exon Smith assert(!Owner && "Unexpected callback to owner");
1614b1bc647SDuncan P. N. Exon Smith PH->Use = static_cast<Metadata **>(Ref);
1624b1bc647SDuncan P. N. Exon Smith return true;
1634b1bc647SDuncan P. N. Exon Smith }
164a7dc087bSChandler Carruth return false;
165a7dc087bSChandler Carruth }
166a7dc087bSChandler Carruth
untrack(void * Ref,Metadata & MD)167a7dc087bSChandler Carruth void MetadataTracking::untrack(void *Ref, Metadata &MD) {
168a7dc087bSChandler Carruth assert(Ref && "Expected live reference");
169fef609f1SDuncan P. N. Exon Smith if (auto *R = ReplaceableMetadataImpl::getIfExists(MD))
170a7dc087bSChandler Carruth R->dropRef(Ref);
1714b1bc647SDuncan P. N. Exon Smith else if (auto *PH = dyn_cast<DistinctMDOperandPlaceholder>(&MD))
1724b1bc647SDuncan P. N. Exon Smith PH->Use = nullptr;
173a7dc087bSChandler Carruth }
174a7dc087bSChandler Carruth
retrack(void * Ref,Metadata & MD,void * New)175a7dc087bSChandler Carruth bool MetadataTracking::retrack(void *Ref, Metadata &MD, void *New) {
176a7dc087bSChandler Carruth assert(Ref && "Expected live reference");
177a7dc087bSChandler Carruth assert(New && "Expected live reference");
178a7dc087bSChandler Carruth assert(Ref != New && "Expected change");
179fef609f1SDuncan P. N. Exon Smith if (auto *R = ReplaceableMetadataImpl::getIfExists(MD)) {
180a7dc087bSChandler Carruth R->moveRef(Ref, New, MD);
181a7dc087bSChandler Carruth return true;
182a7dc087bSChandler Carruth }
1834b1bc647SDuncan P. N. Exon Smith assert(!isa<DistinctMDOperandPlaceholder>(MD) &&
1844b1bc647SDuncan P. N. Exon Smith "Unexpected move of an MDOperand");
185fef609f1SDuncan P. N. Exon Smith assert(!isReplaceable(MD) &&
186fef609f1SDuncan P. N. Exon Smith "Expected un-replaceable metadata, since we didn't move a reference");
187a7dc087bSChandler Carruth return false;
188a7dc087bSChandler Carruth }
189a7dc087bSChandler Carruth
isReplaceable(const Metadata & MD)190a7dc087bSChandler Carruth bool MetadataTracking::isReplaceable(const Metadata &MD) {
191fef609f1SDuncan P. N. Exon Smith return ReplaceableMetadataImpl::isReplaceable(MD);
192a7dc087bSChandler Carruth }
193a7dc087bSChandler Carruth
getAllArgListUsers()194dee2c76bSStephen Tozer SmallVector<Metadata *> ReplaceableMetadataImpl::getAllArgListUsers() {
195dee2c76bSStephen Tozer SmallVector<std::pair<OwnerTy, uint64_t> *> MDUsersWithID;
19665600cb2Sgbtozers for (auto Pair : UseMap) {
19765600cb2Sgbtozers OwnerTy Owner = Pair.second.first;
19865600cb2Sgbtozers if (!Owner.is<Metadata *>())
19965600cb2Sgbtozers continue;
20065600cb2Sgbtozers Metadata *OwnerMD = Owner.get<Metadata *>();
20165600cb2Sgbtozers if (OwnerMD->getMetadataID() == Metadata::DIArgListKind)
202dee2c76bSStephen Tozer MDUsersWithID.push_back(&UseMap[Pair.first]);
20365600cb2Sgbtozers }
204dee2c76bSStephen Tozer llvm::sort(MDUsersWithID, [](auto UserA, auto UserB) {
205dee2c76bSStephen Tozer return UserA->second < UserB->second;
206dee2c76bSStephen Tozer });
207dee2c76bSStephen Tozer SmallVector<Metadata *> MDUsers;
208dee2c76bSStephen Tozer for (auto UserWithID : MDUsersWithID)
209dee2c76bSStephen Tozer MDUsers.push_back(UserWithID->first.get<Metadata *>());
21065600cb2Sgbtozers return MDUsers;
21165600cb2Sgbtozers }
21265600cb2Sgbtozers
addRef(void * Ref,OwnerTy Owner)2135bf8fef5SDuncan P. N. Exon Smith void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) {
21421909e35SDuncan P. N. Exon Smith bool WasInserted =
21521909e35SDuncan P. N. Exon Smith UseMap.insert(std::make_pair(Ref, std::make_pair(Owner, NextIndex)))
21621909e35SDuncan P. N. Exon Smith .second;
2175bf8fef5SDuncan P. N. Exon Smith (void)WasInserted;
2185bf8fef5SDuncan P. N. Exon Smith assert(WasInserted && "Expected to add a reference");
21921909e35SDuncan P. N. Exon Smith
22021909e35SDuncan P. N. Exon Smith ++NextIndex;
22121909e35SDuncan P. N. Exon Smith assert(NextIndex != 0 && "Unexpected overflow");
2225bf8fef5SDuncan P. N. Exon Smith }
2235bf8fef5SDuncan P. N. Exon Smith
dropRef(void * Ref)2245bf8fef5SDuncan P. N. Exon Smith void ReplaceableMetadataImpl::dropRef(void *Ref) {
2255bf8fef5SDuncan P. N. Exon Smith bool WasErased = UseMap.erase(Ref);
2265bf8fef5SDuncan P. N. Exon Smith (void)WasErased;
2275bf8fef5SDuncan P. N. Exon Smith assert(WasErased && "Expected to drop a reference");
2285bf8fef5SDuncan P. N. Exon Smith }
2295bf8fef5SDuncan P. N. Exon Smith
moveRef(void * Ref,void * New,const Metadata & MD)2305bf8fef5SDuncan P. N. Exon Smith void ReplaceableMetadataImpl::moveRef(void *Ref, void *New,
2315bf8fef5SDuncan P. N. Exon Smith const Metadata &MD) {
2325bf8fef5SDuncan P. N. Exon Smith auto I = UseMap.find(Ref);
2335bf8fef5SDuncan P. N. Exon Smith assert(I != UseMap.end() && "Expected to move a reference");
23421909e35SDuncan P. N. Exon Smith auto OwnerAndIndex = I->second;
2355bf8fef5SDuncan P. N. Exon Smith UseMap.erase(I);
23621909e35SDuncan P. N. Exon Smith bool WasInserted = UseMap.insert(std::make_pair(New, OwnerAndIndex)).second;
23721909e35SDuncan P. N. Exon Smith (void)WasInserted;
23821909e35SDuncan P. N. Exon Smith assert(WasInserted && "Expected to add a reference");
2395bf8fef5SDuncan P. N. Exon Smith
2405bf8fef5SDuncan P. N. Exon Smith // Check that the references are direct if there's no owner.
2415bf8fef5SDuncan P. N. Exon Smith (void)MD;
24221909e35SDuncan P. N. Exon Smith assert((OwnerAndIndex.first || *static_cast<Metadata **>(Ref) == &MD) &&
2435bf8fef5SDuncan P. N. Exon Smith "Reference without owner must be direct");
24421909e35SDuncan P. N. Exon Smith assert((OwnerAndIndex.first || *static_cast<Metadata **>(New) == &MD) &&
2455bf8fef5SDuncan P. N. Exon Smith "Reference without owner must be direct");
2465bf8fef5SDuncan P. N. Exon Smith }
2475bf8fef5SDuncan P. N. Exon Smith
SalvageDebugInfo(const Constant & C)248e83543f8SYASHASVI KHATAVKAR void ReplaceableMetadataImpl::SalvageDebugInfo(const Constant &C) {
249e83543f8SYASHASVI KHATAVKAR if (!C.isUsedByMetadata()) {
250e83543f8SYASHASVI KHATAVKAR return;
251e83543f8SYASHASVI KHATAVKAR }
252e83543f8SYASHASVI KHATAVKAR
253e83543f8SYASHASVI KHATAVKAR LLVMContext &Context = C.getType()->getContext();
254e83543f8SYASHASVI KHATAVKAR auto &Store = Context.pImpl->ValuesAsMetadata;
255e83543f8SYASHASVI KHATAVKAR auto I = Store.find(&C);
256e83543f8SYASHASVI KHATAVKAR ValueAsMetadata *MD = I->second;
257e83543f8SYASHASVI KHATAVKAR using UseTy =
258e83543f8SYASHASVI KHATAVKAR std::pair<void *, std::pair<MetadataTracking::OwnerTy, uint64_t>>;
259e83543f8SYASHASVI KHATAVKAR // Copy out uses and update value of Constant used by debug info metadata with undef below
260e83543f8SYASHASVI KHATAVKAR SmallVector<UseTy, 8> Uses(MD->UseMap.begin(), MD->UseMap.end());
261e83543f8SYASHASVI KHATAVKAR
262e83543f8SYASHASVI KHATAVKAR for (const auto &Pair : Uses) {
263e83543f8SYASHASVI KHATAVKAR MetadataTracking::OwnerTy Owner = Pair.second.first;
264e83543f8SYASHASVI KHATAVKAR if (!Owner)
265e83543f8SYASHASVI KHATAVKAR continue;
266e83543f8SYASHASVI KHATAVKAR if (!Owner.is<Metadata *>())
267e83543f8SYASHASVI KHATAVKAR continue;
268e83543f8SYASHASVI KHATAVKAR auto *OwnerMD = dyn_cast<MDNode>(Owner.get<Metadata *>());
269e83543f8SYASHASVI KHATAVKAR if (!OwnerMD)
270e83543f8SYASHASVI KHATAVKAR continue;
271e83543f8SYASHASVI KHATAVKAR if (isa<DINode>(OwnerMD)) {
272e83543f8SYASHASVI KHATAVKAR OwnerMD->handleChangedOperand(
273e83543f8SYASHASVI KHATAVKAR Pair.first, ValueAsMetadata::get(UndefValue::get(C.getType())));
274e83543f8SYASHASVI KHATAVKAR }
275e83543f8SYASHASVI KHATAVKAR }
276e83543f8SYASHASVI KHATAVKAR }
277e83543f8SYASHASVI KHATAVKAR
replaceAllUsesWith(Metadata * MD)2785bf8fef5SDuncan P. N. Exon Smith void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
2795bf8fef5SDuncan P. N. Exon Smith if (UseMap.empty())
2805bf8fef5SDuncan P. N. Exon Smith return;
2815bf8fef5SDuncan P. N. Exon Smith
2825bf8fef5SDuncan P. N. Exon Smith // Copy out uses since UseMap will get touched below.
283de6cce22SEugene Zelenko using UseTy = std::pair<void *, std::pair<OwnerTy, uint64_t>>;
28421909e35SDuncan P. N. Exon Smith SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end());
285e0039b8dSKazu Hirata llvm::sort(Uses, llvm::less_second());
2865bf8fef5SDuncan P. N. Exon Smith for (const auto &Pair : Uses) {
2874a4f7858SDuncan P. N. Exon Smith // Check that this Ref hasn't disappeared after RAUW (when updating a
2884a4f7858SDuncan P. N. Exon Smith // previous Ref).
2894a4f7858SDuncan P. N. Exon Smith if (!UseMap.count(Pair.first))
2904a4f7858SDuncan P. N. Exon Smith continue;
2914a4f7858SDuncan P. N. Exon Smith
29221909e35SDuncan P. N. Exon Smith OwnerTy Owner = Pair.second.first;
29321909e35SDuncan P. N. Exon Smith if (!Owner) {
2945bf8fef5SDuncan P. N. Exon Smith // Update unowned tracking references directly.
2955bf8fef5SDuncan P. N. Exon Smith Metadata *&Ref = *static_cast<Metadata **>(Pair.first);
2965bf8fef5SDuncan P. N. Exon Smith Ref = MD;
297121eeff4SDuncan P. N. Exon Smith if (MD)
2985bf8fef5SDuncan P. N. Exon Smith MetadataTracking::track(Ref);
2995bf8fef5SDuncan P. N. Exon Smith UseMap.erase(Pair.first);
3005bf8fef5SDuncan P. N. Exon Smith continue;
3015bf8fef5SDuncan P. N. Exon Smith }
3025bf8fef5SDuncan P. N. Exon Smith
3035bf8fef5SDuncan P. N. Exon Smith // Check for MetadataAsValue.
30421909e35SDuncan P. N. Exon Smith if (Owner.is<MetadataAsValue *>()) {
30521909e35SDuncan P. N. Exon Smith Owner.get<MetadataAsValue *>()->handleChangedMetadata(MD);
3065bf8fef5SDuncan P. N. Exon Smith continue;
3075bf8fef5SDuncan P. N. Exon Smith }
3085bf8fef5SDuncan P. N. Exon Smith
3095bf8fef5SDuncan P. N. Exon Smith // There's a Metadata owner -- dispatch.
31021909e35SDuncan P. N. Exon Smith Metadata *OwnerMD = Owner.get<Metadata *>();
31121909e35SDuncan P. N. Exon Smith switch (OwnerMD->getMetadataID()) {
3125bf8fef5SDuncan P. N. Exon Smith #define HANDLE_METADATA_LEAF(CLASS) \
3135bf8fef5SDuncan P. N. Exon Smith case Metadata::CLASS##Kind: \
31421909e35SDuncan P. N. Exon Smith cast<CLASS>(OwnerMD)->handleChangedOperand(Pair.first, MD); \
3155bf8fef5SDuncan P. N. Exon Smith continue;
3165bf8fef5SDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
3175bf8fef5SDuncan P. N. Exon Smith default:
3185bf8fef5SDuncan P. N. Exon Smith llvm_unreachable("Invalid metadata subclass");
3195bf8fef5SDuncan P. N. Exon Smith }
3205bf8fef5SDuncan P. N. Exon Smith }
3215bf8fef5SDuncan P. N. Exon Smith assert(UseMap.empty() && "Expected all uses to be replaced");
3225bf8fef5SDuncan P. N. Exon Smith }
3235bf8fef5SDuncan P. N. Exon Smith
resolveAllUses(bool ResolveUsers)3245bf8fef5SDuncan P. N. Exon Smith void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
3255bf8fef5SDuncan P. N. Exon Smith if (UseMap.empty())
3265bf8fef5SDuncan P. N. Exon Smith return;
3275bf8fef5SDuncan P. N. Exon Smith
3285bf8fef5SDuncan P. N. Exon Smith if (!ResolveUsers) {
3295bf8fef5SDuncan P. N. Exon Smith UseMap.clear();
3305bf8fef5SDuncan P. N. Exon Smith return;
3315bf8fef5SDuncan P. N. Exon Smith }
3325bf8fef5SDuncan P. N. Exon Smith
3335bf8fef5SDuncan P. N. Exon Smith // Copy out uses since UseMap could get touched below.
334de6cce22SEugene Zelenko using UseTy = std::pair<void *, std::pair<OwnerTy, uint64_t>>;
33521909e35SDuncan P. N. Exon Smith SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end());
3360cac726aSFangrui Song llvm::sort(Uses, [](const UseTy &L, const UseTy &R) {
33721909e35SDuncan P. N. Exon Smith return L.second.second < R.second.second;
33821909e35SDuncan P. N. Exon Smith });
3395bf8fef5SDuncan P. N. Exon Smith UseMap.clear();
3405bf8fef5SDuncan P. N. Exon Smith for (const auto &Pair : Uses) {
34121909e35SDuncan P. N. Exon Smith auto Owner = Pair.second.first;
34221909e35SDuncan P. N. Exon Smith if (!Owner)
3435bf8fef5SDuncan P. N. Exon Smith continue;
34421909e35SDuncan P. N. Exon Smith if (Owner.is<MetadataAsValue *>())
3455bf8fef5SDuncan P. N. Exon Smith continue;
3465bf8fef5SDuncan P. N. Exon Smith
3472bc00f4aSDuncan P. N. Exon Smith // Resolve MDNodes that point at this.
3482bc00f4aSDuncan P. N. Exon Smith auto *OwnerMD = dyn_cast<MDNode>(Owner.get<Metadata *>());
34921909e35SDuncan P. N. Exon Smith if (!OwnerMD)
3505bf8fef5SDuncan P. N. Exon Smith continue;
35121909e35SDuncan P. N. Exon Smith if (OwnerMD->isResolved())
3525bf8fef5SDuncan P. N. Exon Smith continue;
35334c3d103SDuncan P. N. Exon Smith OwnerMD->decrementUnresolvedOperandCount();
3545bf8fef5SDuncan P. N. Exon Smith }
3555bf8fef5SDuncan P. N. Exon Smith }
3565bf8fef5SDuncan P. N. Exon Smith
getOrCreate(Metadata & MD)357fef609f1SDuncan P. N. Exon Smith ReplaceableMetadataImpl *ReplaceableMetadataImpl::getOrCreate(Metadata &MD) {
358a7dc087bSChandler Carruth if (auto *N = dyn_cast<MDNode>(&MD))
359fef609f1SDuncan P. N. Exon Smith return N->isResolved() ? nullptr : N->Context.getOrCreateReplaceableUses();
360fef609f1SDuncan P. N. Exon Smith return dyn_cast<ValueAsMetadata>(&MD);
361fef609f1SDuncan P. N. Exon Smith }
362fef609f1SDuncan P. N. Exon Smith
getIfExists(Metadata & MD)363fef609f1SDuncan P. N. Exon Smith ReplaceableMetadataImpl *ReplaceableMetadataImpl::getIfExists(Metadata &MD) {
364fef609f1SDuncan P. N. Exon Smith if (auto *N = dyn_cast<MDNode>(&MD))
365fef609f1SDuncan P. N. Exon Smith return N->isResolved() ? nullptr : N->Context.getReplaceableUses();
366fef609f1SDuncan P. N. Exon Smith return dyn_cast<ValueAsMetadata>(&MD);
367fef609f1SDuncan P. N. Exon Smith }
368fef609f1SDuncan P. N. Exon Smith
isReplaceable(const Metadata & MD)369fef609f1SDuncan P. N. Exon Smith bool ReplaceableMetadataImpl::isReplaceable(const Metadata &MD) {
370fef609f1SDuncan P. N. Exon Smith if (auto *N = dyn_cast<MDNode>(&MD))
371fef609f1SDuncan P. N. Exon Smith return !N->isResolved();
372d243cbf8SKazu Hirata return isa<ValueAsMetadata>(&MD);
373a7dc087bSChandler Carruth }
374a7dc087bSChandler Carruth
getLocalFunctionMetadata(Value * V)3759208e8fbSPetar Jovanovic static DISubprogram *getLocalFunctionMetadata(Value *V) {
3765bf8fef5SDuncan P. N. Exon Smith assert(V && "Expected value");
3779208e8fbSPetar Jovanovic if (auto *A = dyn_cast<Argument>(V)) {
3789208e8fbSPetar Jovanovic if (auto *Fn = A->getParent())
3799208e8fbSPetar Jovanovic return Fn->getSubprogram();
3809208e8fbSPetar Jovanovic return nullptr;
3819208e8fbSPetar Jovanovic }
3829208e8fbSPetar Jovanovic
3839208e8fbSPetar Jovanovic if (BasicBlock *BB = cast<Instruction>(V)->getParent()) {
3849208e8fbSPetar Jovanovic if (auto *Fn = BB->getParent())
3859208e8fbSPetar Jovanovic return Fn->getSubprogram();
3869208e8fbSPetar Jovanovic return nullptr;
3879208e8fbSPetar Jovanovic }
3889208e8fbSPetar Jovanovic
3895bf8fef5SDuncan P. N. Exon Smith return nullptr;
3905bf8fef5SDuncan P. N. Exon Smith }
3915bf8fef5SDuncan P. N. Exon Smith
get(Value * V)3925bf8fef5SDuncan P. N. Exon Smith ValueAsMetadata *ValueAsMetadata::get(Value *V) {
3935bf8fef5SDuncan P. N. Exon Smith assert(V && "Unexpected null Value");
3945bf8fef5SDuncan P. N. Exon Smith
3955bf8fef5SDuncan P. N. Exon Smith auto &Context = V->getContext();
3965bf8fef5SDuncan P. N. Exon Smith auto *&Entry = Context.pImpl->ValuesAsMetadata[V];
3975bf8fef5SDuncan P. N. Exon Smith if (!Entry) {
3985bf8fef5SDuncan P. N. Exon Smith assert((isa<Constant>(V) || isa<Argument>(V) || isa<Instruction>(V)) &&
3995bf8fef5SDuncan P. N. Exon Smith "Expected constant or function-local value");
400e0e0ed13SDehao Chen assert(!V->IsUsedByMD && "Expected this to be the only metadata use");
4017349ab93SOwen Anderson V->IsUsedByMD = true;
4025bf8fef5SDuncan P. N. Exon Smith if (auto *C = dyn_cast<Constant>(V))
4031c00c9f7SDuncan P. N. Exon Smith Entry = new ConstantAsMetadata(C);
4045bf8fef5SDuncan P. N. Exon Smith else
4051c00c9f7SDuncan P. N. Exon Smith Entry = new LocalAsMetadata(V);
4065bf8fef5SDuncan P. N. Exon Smith }
4075bf8fef5SDuncan P. N. Exon Smith
4085bf8fef5SDuncan P. N. Exon Smith return Entry;
4095bf8fef5SDuncan P. N. Exon Smith }
4105bf8fef5SDuncan P. N. Exon Smith
getIfExists(Value * V)4115bf8fef5SDuncan P. N. Exon Smith ValueAsMetadata *ValueAsMetadata::getIfExists(Value *V) {
4125bf8fef5SDuncan P. N. Exon Smith assert(V && "Unexpected null Value");
4135bf8fef5SDuncan P. N. Exon Smith return V->getContext().pImpl->ValuesAsMetadata.lookup(V);
4145bf8fef5SDuncan P. N. Exon Smith }
4155bf8fef5SDuncan P. N. Exon Smith
handleDeletion(Value * V)4165bf8fef5SDuncan P. N. Exon Smith void ValueAsMetadata::handleDeletion(Value *V) {
4175bf8fef5SDuncan P. N. Exon Smith assert(V && "Expected valid value");
4185bf8fef5SDuncan P. N. Exon Smith
4195bf8fef5SDuncan P. N. Exon Smith auto &Store = V->getType()->getContext().pImpl->ValuesAsMetadata;
4205bf8fef5SDuncan P. N. Exon Smith auto I = Store.find(V);
4215bf8fef5SDuncan P. N. Exon Smith if (I == Store.end())
4225bf8fef5SDuncan P. N. Exon Smith return;
4235bf8fef5SDuncan P. N. Exon Smith
4245bf8fef5SDuncan P. N. Exon Smith // Remove old entry from the map.
4255bf8fef5SDuncan P. N. Exon Smith ValueAsMetadata *MD = I->second;
4265bf8fef5SDuncan P. N. Exon Smith assert(MD && "Expected valid metadata");
4275bf8fef5SDuncan P. N. Exon Smith assert(MD->getValue() == V && "Expected valid mapping");
4285bf8fef5SDuncan P. N. Exon Smith Store.erase(I);
4295bf8fef5SDuncan P. N. Exon Smith
4305bf8fef5SDuncan P. N. Exon Smith // Delete the metadata.
4315bf8fef5SDuncan P. N. Exon Smith MD->replaceAllUsesWith(nullptr);
4325bf8fef5SDuncan P. N. Exon Smith delete MD;
4335bf8fef5SDuncan P. N. Exon Smith }
4345bf8fef5SDuncan P. N. Exon Smith
handleRAUW(Value * From,Value * To)4355bf8fef5SDuncan P. N. Exon Smith void ValueAsMetadata::handleRAUW(Value *From, Value *To) {
4365bf8fef5SDuncan P. N. Exon Smith assert(From && "Expected valid value");
4375bf8fef5SDuncan P. N. Exon Smith assert(To && "Expected valid value");
4385bf8fef5SDuncan P. N. Exon Smith assert(From != To && "Expected changed value");
4395bf8fef5SDuncan P. N. Exon Smith assert(From->getType() == To->getType() && "Unexpected type change");
4405bf8fef5SDuncan P. N. Exon Smith
4415bf8fef5SDuncan P. N. Exon Smith LLVMContext &Context = From->getType()->getContext();
4425bf8fef5SDuncan P. N. Exon Smith auto &Store = Context.pImpl->ValuesAsMetadata;
4435bf8fef5SDuncan P. N. Exon Smith auto I = Store.find(From);
4445bf8fef5SDuncan P. N. Exon Smith if (I == Store.end()) {
445e0e0ed13SDehao Chen assert(!From->IsUsedByMD && "Expected From not to be used by metadata");
4465bf8fef5SDuncan P. N. Exon Smith return;
4475bf8fef5SDuncan P. N. Exon Smith }
4485bf8fef5SDuncan P. N. Exon Smith
4495bf8fef5SDuncan P. N. Exon Smith // Remove old entry from the map.
450e0e0ed13SDehao Chen assert(From->IsUsedByMD && "Expected From to be used by metadata");
4517349ab93SOwen Anderson From->IsUsedByMD = false;
4525bf8fef5SDuncan P. N. Exon Smith ValueAsMetadata *MD = I->second;
4535bf8fef5SDuncan P. N. Exon Smith assert(MD && "Expected valid metadata");
4545bf8fef5SDuncan P. N. Exon Smith assert(MD->getValue() == From && "Expected valid mapping");
4555bf8fef5SDuncan P. N. Exon Smith Store.erase(I);
4565bf8fef5SDuncan P. N. Exon Smith
4575bf8fef5SDuncan P. N. Exon Smith if (isa<LocalAsMetadata>(MD)) {
4585bf8fef5SDuncan P. N. Exon Smith if (auto *C = dyn_cast<Constant>(To)) {
4595bf8fef5SDuncan P. N. Exon Smith // Local became a constant.
4605bf8fef5SDuncan P. N. Exon Smith MD->replaceAllUsesWith(ConstantAsMetadata::get(C));
4615bf8fef5SDuncan P. N. Exon Smith delete MD;
4625bf8fef5SDuncan P. N. Exon Smith return;
4635bf8fef5SDuncan P. N. Exon Smith }
4649208e8fbSPetar Jovanovic if (getLocalFunctionMetadata(From) && getLocalFunctionMetadata(To) &&
4659208e8fbSPetar Jovanovic getLocalFunctionMetadata(From) != getLocalFunctionMetadata(To)) {
4669208e8fbSPetar Jovanovic // DISubprogram changed.
4675bf8fef5SDuncan P. N. Exon Smith MD->replaceAllUsesWith(nullptr);
4685bf8fef5SDuncan P. N. Exon Smith delete MD;
4695bf8fef5SDuncan P. N. Exon Smith return;
4705bf8fef5SDuncan P. N. Exon Smith }
4715bf8fef5SDuncan P. N. Exon Smith } else if (!isa<Constant>(To)) {
4725bf8fef5SDuncan P. N. Exon Smith // Changed to function-local value.
4735bf8fef5SDuncan P. N. Exon Smith MD->replaceAllUsesWith(nullptr);
4745bf8fef5SDuncan P. N. Exon Smith delete MD;
4755bf8fef5SDuncan P. N. Exon Smith return;
4765bf8fef5SDuncan P. N. Exon Smith }
4775bf8fef5SDuncan P. N. Exon Smith
4785bf8fef5SDuncan P. N. Exon Smith auto *&Entry = Store[To];
4795bf8fef5SDuncan P. N. Exon Smith if (Entry) {
4805bf8fef5SDuncan P. N. Exon Smith // The target already exists.
4815bf8fef5SDuncan P. N. Exon Smith MD->replaceAllUsesWith(Entry);
4825bf8fef5SDuncan P. N. Exon Smith delete MD;
4835bf8fef5SDuncan P. N. Exon Smith return;
4845bf8fef5SDuncan P. N. Exon Smith }
4855bf8fef5SDuncan P. N. Exon Smith
4865bf8fef5SDuncan P. N. Exon Smith // Update MD in place (and update the map entry).
487e0e0ed13SDehao Chen assert(!To->IsUsedByMD && "Expected this to be the only metadata use");
4887349ab93SOwen Anderson To->IsUsedByMD = true;
4895bf8fef5SDuncan P. N. Exon Smith MD->V = To;
4905bf8fef5SDuncan P. N. Exon Smith Entry = MD;
4915bf8fef5SDuncan P. N. Exon Smith }
492a69934fdSDuncan P. N. Exon Smith
493ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
494ef860a24SChandler Carruth // MDString implementation.
495ef860a24SChandler Carruth //
496ef860a24SChandler Carruth
get(LLVMContext & Context,StringRef Str)497ef860a24SChandler Carruth MDString *MDString::get(LLVMContext &Context, StringRef Str) {
498f17e7401SDuncan P. N. Exon Smith auto &Store = Context.pImpl->MDStringCache;
499eab3d367SBenjamin Kramer auto I = Store.try_emplace(Str);
500cb708b26SMehdi Amini auto &MapEntry = I.first->getValue();
501cb708b26SMehdi Amini if (!I.second)
502cb708b26SMehdi Amini return &MapEntry;
503cb708b26SMehdi Amini MapEntry.Entry = &*I.first;
504cb708b26SMehdi Amini return &MapEntry;
505f17e7401SDuncan P. N. Exon Smith }
506f17e7401SDuncan P. N. Exon Smith
getString() const507f17e7401SDuncan P. N. Exon Smith StringRef MDString::getString() const {
508c1a664feSDuncan P. N. Exon Smith assert(Entry && "Expected to find string map entry");
509c1a664feSDuncan P. N. Exon Smith return Entry->first();
510ef860a24SChandler Carruth }
511ef860a24SChandler Carruth
512ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
513ef860a24SChandler Carruth // MDNode implementation.
514ef860a24SChandler Carruth //
515ef860a24SChandler Carruth
5168096d34eSJames Y Knight // Assert that the MDNode types will not be unaligned by the objects
5178096d34eSJames Y Knight // prepended to them.
5188096d34eSJames Y Knight #define HANDLE_MDNODE_LEAF(CLASS) \
519f27e4413SJames Y Knight static_assert( \
520b2505005SBenjamin Kramer alignof(uint64_t) >= alignof(CLASS), \
521f27e4413SJames Y Knight "Alignment is insufficient after objects prepended to " #CLASS);
5228096d34eSJames Y Knight #include "llvm/IR/Metadata.def"
5238096d34eSJames Y Knight
operator new(size_t Size,size_t NumOps,StorageType Storage)524*a630ea30SWolfgang Pieb void *MDNode::operator new(size_t Size, size_t NumOps, StorageType Storage) {
5258096d34eSJames Y Knight // uint64_t is the most aligned type we need support (ensured by static_assert
5268096d34eSJames Y Knight // above)
527*a630ea30SWolfgang Pieb size_t AllocSize =
528*a630ea30SWolfgang Pieb alignTo(Header::getAllocSize(Storage, NumOps), alignof(uint64_t));
5292740c187SWolfgang Pieb char *Mem = reinterpret_cast<char *>(::operator new(AllocSize + Size));
530*a630ea30SWolfgang Pieb Header *H = new (Mem + AllocSize - sizeof(Header)) Header(NumOps, Storage);
5312740c187SWolfgang Pieb return reinterpret_cast<void *>(H + 1);
532c23610b1SDuncan P. N. Exon Smith }
533c23610b1SDuncan P. N. Exon Smith
operator delete(void * N)5342740c187SWolfgang Pieb void MDNode::operator delete(void *N) {
5352740c187SWolfgang Pieb Header *H = reinterpret_cast<Header *>(N) - 1;
5362740c187SWolfgang Pieb void *Mem = H->getAllocation();
5372740c187SWolfgang Pieb H->~Header();
5382740c187SWolfgang Pieb ::operator delete(Mem);
539c23610b1SDuncan P. N. Exon Smith }
540c23610b1SDuncan P. N. Exon Smith
MDNode(LLVMContext & Context,unsigned ID,StorageType Storage,ArrayRef<Metadata * > Ops1,ArrayRef<Metadata * > Ops2)541f1340453SDuncan P. N. Exon Smith MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
542fed199a7SDuncan P. N. Exon Smith ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2)
5432740c187SWolfgang Pieb : Metadata(ID, Storage), Context(Context) {
544fed199a7SDuncan P. N. Exon Smith unsigned Op = 0;
545fed199a7SDuncan P. N. Exon Smith for (Metadata *MD : Ops1)
546fed199a7SDuncan P. N. Exon Smith setOperand(Op++, MD);
547fed199a7SDuncan P. N. Exon Smith for (Metadata *MD : Ops2)
548fed199a7SDuncan P. N. Exon Smith setOperand(Op++, MD);
5492711ca7cSDuncan P. N. Exon Smith
550fef609f1SDuncan P. N. Exon Smith if (!isUniqued())
5515e5b8509SDuncan P. N. Exon Smith return;
5525e5b8509SDuncan P. N. Exon Smith
553fef609f1SDuncan P. N. Exon Smith // Count the unresolved operands. If there are any, RAUW support will be
554fef609f1SDuncan P. N. Exon Smith // added lazily on first reference.
555fef609f1SDuncan P. N. Exon Smith countUnresolvedOperands();
556a1ae4f6bSDuncan P. N. Exon Smith }
557a1ae4f6bSDuncan P. N. Exon Smith
clone() const55803e0583aSDuncan P. N. Exon Smith TempMDNode MDNode::clone() const {
55903e0583aSDuncan P. N. Exon Smith switch (getMetadataID()) {
56003e0583aSDuncan P. N. Exon Smith default:
56103e0583aSDuncan P. N. Exon Smith llvm_unreachable("Invalid MDNode subclass");
56203e0583aSDuncan P. N. Exon Smith #define HANDLE_MDNODE_LEAF(CLASS) \
56303e0583aSDuncan P. N. Exon Smith case CLASS##Kind: \
56403e0583aSDuncan P. N. Exon Smith return cast<CLASS>(this)->cloneImpl();
56503e0583aSDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
56603e0583aSDuncan P. N. Exon Smith }
56703e0583aSDuncan P. N. Exon Smith }
56803e0583aSDuncan P. N. Exon Smith
Header(size_t NumOps,StorageType Storage)569*a630ea30SWolfgang Pieb MDNode::Header::Header(size_t NumOps, StorageType Storage) {
570*a630ea30SWolfgang Pieb IsLarge = isLarge(NumOps);
571*a630ea30SWolfgang Pieb IsResizable = isResizable(Storage);
572*a630ea30SWolfgang Pieb SmallSize = getSmallSize(NumOps, IsResizable, IsLarge);
573*a630ea30SWolfgang Pieb if (IsLarge) {
574*a630ea30SWolfgang Pieb SmallNumOps = 0;
575*a630ea30SWolfgang Pieb new (getLargePtr()) LargeStorageVector();
576*a630ea30SWolfgang Pieb getLarge().resize(NumOps);
577*a630ea30SWolfgang Pieb return;
578*a630ea30SWolfgang Pieb }
579*a630ea30SWolfgang Pieb SmallNumOps = NumOps;
580*a630ea30SWolfgang Pieb MDOperand *O = reinterpret_cast<MDOperand *>(this) - SmallSize;
581*a630ea30SWolfgang Pieb for (MDOperand *E = O + SmallSize; O != E;)
582*a630ea30SWolfgang Pieb (void)new (O++) MDOperand();
5832740c187SWolfgang Pieb }
5842740c187SWolfgang Pieb
~Header()5852740c187SWolfgang Pieb MDNode::Header::~Header() {
586*a630ea30SWolfgang Pieb if (IsLarge) {
587*a630ea30SWolfgang Pieb getLarge().~LargeStorageVector();
588*a630ea30SWolfgang Pieb return;
589*a630ea30SWolfgang Pieb }
590*a630ea30SWolfgang Pieb MDOperand *O = reinterpret_cast<MDOperand *>(this);
591*a630ea30SWolfgang Pieb for (MDOperand *E = O - SmallSize; O != E; --O)
592*a630ea30SWolfgang Pieb (void)(O - 1)->~MDOperand();
593*a630ea30SWolfgang Pieb }
594*a630ea30SWolfgang Pieb
getSmallPtr()595*a630ea30SWolfgang Pieb void *MDNode::Header::getSmallPtr() {
596*a630ea30SWolfgang Pieb static_assert(alignof(MDOperand) <= alignof(Header),
597*a630ea30SWolfgang Pieb "MDOperand too strongly aligned");
598*a630ea30SWolfgang Pieb return reinterpret_cast<char *>(const_cast<Header *>(this)) -
599*a630ea30SWolfgang Pieb sizeof(MDOperand) * SmallSize;
600*a630ea30SWolfgang Pieb }
601*a630ea30SWolfgang Pieb
resize(size_t NumOps)602*a630ea30SWolfgang Pieb void MDNode::Header::resize(size_t NumOps) {
603*a630ea30SWolfgang Pieb assert(IsResizable && "Node is not resizable");
604*a630ea30SWolfgang Pieb if (operands().size() == NumOps)
605*a630ea30SWolfgang Pieb return;
606*a630ea30SWolfgang Pieb
607*a630ea30SWolfgang Pieb if (IsLarge)
608*a630ea30SWolfgang Pieb getLarge().resize(NumOps);
609*a630ea30SWolfgang Pieb else if (NumOps <= SmallSize)
610*a630ea30SWolfgang Pieb resizeSmall(NumOps);
611*a630ea30SWolfgang Pieb else
612*a630ea30SWolfgang Pieb resizeSmallToLarge(NumOps);
613*a630ea30SWolfgang Pieb }
614*a630ea30SWolfgang Pieb
resizeSmall(size_t NumOps)615*a630ea30SWolfgang Pieb void MDNode::Header::resizeSmall(size_t NumOps) {
616*a630ea30SWolfgang Pieb assert(!IsLarge && "Expected a small MDNode");
617*a630ea30SWolfgang Pieb assert(NumOps <= SmallSize && "NumOps too large for small resize");
618*a630ea30SWolfgang Pieb
619*a630ea30SWolfgang Pieb MutableArrayRef<MDOperand> ExistingOps = operands();
620*a630ea30SWolfgang Pieb assert(NumOps != ExistingOps.size() && "Expected a different size");
621*a630ea30SWolfgang Pieb
622*a630ea30SWolfgang Pieb int NumNew = (int)NumOps - (int)ExistingOps.size();
623*a630ea30SWolfgang Pieb MDOperand *O = ExistingOps.end();
624*a630ea30SWolfgang Pieb for (int I = 0, E = NumNew; I < E; ++I)
625*a630ea30SWolfgang Pieb (O++)->reset();
626*a630ea30SWolfgang Pieb for (int I = 0, E = NumNew; I > E; --I)
627*a630ea30SWolfgang Pieb (--O)->reset();
628*a630ea30SWolfgang Pieb SmallNumOps = NumOps;
629*a630ea30SWolfgang Pieb assert(O == operands().end() && "Operands not (un)initialized until the end");
630*a630ea30SWolfgang Pieb }
631*a630ea30SWolfgang Pieb
resizeSmallToLarge(size_t NumOps)632*a630ea30SWolfgang Pieb void MDNode::Header::resizeSmallToLarge(size_t NumOps) {
633*a630ea30SWolfgang Pieb assert(!IsLarge && "Expected a small MDNode");
634*a630ea30SWolfgang Pieb assert(NumOps > SmallSize && "Expected NumOps to be larger than allocation");
635*a630ea30SWolfgang Pieb LargeStorageVector NewOps;
636*a630ea30SWolfgang Pieb NewOps.resize(NumOps);
637*a630ea30SWolfgang Pieb llvm::move(operands(), NewOps.begin());
638*a630ea30SWolfgang Pieb resizeSmall(0);
639*a630ea30SWolfgang Pieb new (getLargePtr()) LargeStorageVector(std::move(NewOps));
640*a630ea30SWolfgang Pieb IsLarge = true;
6412740c187SWolfgang Pieb }
6422740c187SWolfgang Pieb
isOperandUnresolved(Metadata * Op)6432bc00f4aSDuncan P. N. Exon Smith static bool isOperandUnresolved(Metadata *Op) {
6442bc00f4aSDuncan P. N. Exon Smith if (auto *N = dyn_cast_or_null<MDNode>(Op))
6452bc00f4aSDuncan P. N. Exon Smith return !N->isResolved();
6462bc00f4aSDuncan P. N. Exon Smith return false;
6472bc00f4aSDuncan P. N. Exon Smith }
6482bc00f4aSDuncan P. N. Exon Smith
countUnresolvedOperands()649fef609f1SDuncan P. N. Exon Smith void MDNode::countUnresolvedOperands() {
6502740c187SWolfgang Pieb assert(getNumUnresolved() == 0 && "Expected unresolved ops to be uncounted");
651fef609f1SDuncan P. N. Exon Smith assert(isUniqued() && "Expected this to be uniqued");
6522740c187SWolfgang Pieb setNumUnresolved(count_if(operands(), isOperandUnresolved));
653c5a0e2e3SDuncan P. N. Exon Smith }
654c5a0e2e3SDuncan P. N. Exon Smith
makeUniqued()6552bc00f4aSDuncan P. N. Exon Smith void MDNode::makeUniqued() {
656e3353090SDuncan P. N. Exon Smith assert(isTemporary() && "Expected this to be temporary");
657e3353090SDuncan P. N. Exon Smith assert(!isResolved() && "Expected this to be unresolved");
658e3353090SDuncan P. N. Exon Smith
659cb33d6f5SDuncan P. N. Exon Smith // Enable uniquing callbacks.
660cb33d6f5SDuncan P. N. Exon Smith for (auto &Op : mutable_operands())
661cb33d6f5SDuncan P. N. Exon Smith Op.reset(Op.get(), this);
662cb33d6f5SDuncan P. N. Exon Smith
663e3353090SDuncan P. N. Exon Smith // Make this 'uniqued'.
664e3353090SDuncan P. N. Exon Smith Storage = Uniqued;
665fef609f1SDuncan P. N. Exon Smith countUnresolvedOperands();
6662740c187SWolfgang Pieb if (!getNumUnresolved()) {
667fef609f1SDuncan P. N. Exon Smith dropReplaceableUses();
668fef609f1SDuncan P. N. Exon Smith assert(isResolved() && "Expected this to be resolved");
669fef609f1SDuncan P. N. Exon Smith }
670e3353090SDuncan P. N. Exon Smith
671e3353090SDuncan P. N. Exon Smith assert(isUniqued() && "Expected this to be uniqued");
672e3353090SDuncan P. N. Exon Smith }
673e3353090SDuncan P. N. Exon Smith
makeDistinct()6742bc00f4aSDuncan P. N. Exon Smith void MDNode::makeDistinct() {
675e3353090SDuncan P. N. Exon Smith assert(isTemporary() && "Expected this to be temporary");
676e3353090SDuncan P. N. Exon Smith assert(!isResolved() && "Expected this to be unresolved");
677e3353090SDuncan P. N. Exon Smith
678fef609f1SDuncan P. N. Exon Smith // Drop RAUW support and store as a distinct node.
679fef609f1SDuncan P. N. Exon Smith dropReplaceableUses();
680e3353090SDuncan P. N. Exon Smith storeDistinctInContext();
681e3353090SDuncan P. N. Exon Smith
682e3353090SDuncan P. N. Exon Smith assert(isDistinct() && "Expected this to be distinct");
683e3353090SDuncan P. N. Exon Smith assert(isResolved() && "Expected this to be resolved");
684e3353090SDuncan P. N. Exon Smith }
685e3353090SDuncan P. N. Exon Smith
resolve()6862bc00f4aSDuncan P. N. Exon Smith void MDNode::resolve() {
687b8f79603SDuncan P. N. Exon Smith assert(isUniqued() && "Expected this to be uniqued");
6885bf8fef5SDuncan P. N. Exon Smith assert(!isResolved() && "Expected this to be unresolved");
6895bf8fef5SDuncan P. N. Exon Smith
6902740c187SWolfgang Pieb setNumUnresolved(0);
691fef609f1SDuncan P. N. Exon Smith dropReplaceableUses();
6925bf8fef5SDuncan P. N. Exon Smith
693fef609f1SDuncan P. N. Exon Smith assert(isResolved() && "Expected this to be resolved");
694fef609f1SDuncan P. N. Exon Smith }
695fef609f1SDuncan P. N. Exon Smith
dropReplaceableUses()696fef609f1SDuncan P. N. Exon Smith void MDNode::dropReplaceableUses() {
6972740c187SWolfgang Pieb assert(!getNumUnresolved() && "Unexpected unresolved operand");
698fef609f1SDuncan P. N. Exon Smith
699fef609f1SDuncan P. N. Exon Smith // Drop any RAUW support.
700fef609f1SDuncan P. N. Exon Smith if (Context.hasReplaceableUses())
701fef609f1SDuncan P. N. Exon Smith Context.takeReplaceableUses()->resolveAllUses();
70250846f80SDuncan P. N. Exon Smith }
70350846f80SDuncan P. N. Exon Smith
resolveAfterOperandChange(Metadata * Old,Metadata * New)7042bc00f4aSDuncan P. N. Exon Smith void MDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
705fef609f1SDuncan P. N. Exon Smith assert(isUniqued() && "Expected this to be uniqued");
7062740c187SWolfgang Pieb assert(getNumUnresolved() != 0 && "Expected unresolved operands");
7073a16d80aSDuncan P. N. Exon Smith
7080c87d771SDuncan P. N. Exon Smith // Check if an operand was resolved.
709845755c4SDuncan P. N. Exon Smith if (!isOperandUnresolved(Old)) {
710845755c4SDuncan P. N. Exon Smith if (isOperandUnresolved(New))
711845755c4SDuncan P. N. Exon Smith // An operand was un-resolved!
7122740c187SWolfgang Pieb setNumUnresolved(getNumUnresolved() + 1);
713845755c4SDuncan P. N. Exon Smith } else if (!isOperandUnresolved(New))
7140c87d771SDuncan P. N. Exon Smith decrementUnresolvedOperandCount();
7153a16d80aSDuncan P. N. Exon Smith }
7163a16d80aSDuncan P. N. Exon Smith
decrementUnresolvedOperandCount()7172bc00f4aSDuncan P. N. Exon Smith void MDNode::decrementUnresolvedOperandCount() {
718fef609f1SDuncan P. N. Exon Smith assert(!isResolved() && "Expected this to be unresolved");
719fef609f1SDuncan P. N. Exon Smith if (isTemporary())
720fef609f1SDuncan P. N. Exon Smith return;
721fef609f1SDuncan P. N. Exon Smith
722fef609f1SDuncan P. N. Exon Smith assert(isUniqued() && "Expected this to be uniqued");
7232740c187SWolfgang Pieb setNumUnresolved(getNumUnresolved() - 1);
7242740c187SWolfgang Pieb if (getNumUnresolved())
725fef609f1SDuncan P. N. Exon Smith return;
726fef609f1SDuncan P. N. Exon Smith
7270c87d771SDuncan P. N. Exon Smith // Last unresolved operand has just been resolved.
728fef609f1SDuncan P. N. Exon Smith dropReplaceableUses();
729fef609f1SDuncan P. N. Exon Smith assert(isResolved() && "Expected this to become resolved");
73034c3d103SDuncan P. N. Exon Smith }
73134c3d103SDuncan P. N. Exon Smith
resolveCycles()732b703c77bSTeresa Johnson void MDNode::resolveCycles() {
7335bf8fef5SDuncan P. N. Exon Smith if (isResolved())
7345bf8fef5SDuncan P. N. Exon Smith return;
7355bf8fef5SDuncan P. N. Exon Smith
7365bf8fef5SDuncan P. N. Exon Smith // Resolve this node immediately.
7375bf8fef5SDuncan P. N. Exon Smith resolve();
7385bf8fef5SDuncan P. N. Exon Smith
7395bf8fef5SDuncan P. N. Exon Smith // Resolve all operands.
7405bf8fef5SDuncan P. N. Exon Smith for (const auto &Op : operands()) {
7412bc00f4aSDuncan P. N. Exon Smith auto *N = dyn_cast_or_null<MDNode>(Op);
742946fdcc5SDuncan P. N. Exon Smith if (!N)
7435bf8fef5SDuncan P. N. Exon Smith continue;
744946fdcc5SDuncan P. N. Exon Smith
745946fdcc5SDuncan P. N. Exon Smith assert(!N->isTemporary() &&
7465bf8fef5SDuncan P. N. Exon Smith "Expected all forward declarations to be resolved");
7475bf8fef5SDuncan P. N. Exon Smith if (!N->isResolved())
7485bf8fef5SDuncan P. N. Exon Smith N->resolveCycles();
7495bf8fef5SDuncan P. N. Exon Smith }
750ef860a24SChandler Carruth }
751ef860a24SChandler Carruth
hasSelfReference(MDNode * N)7524ee4a98eSDuncan P. N. Exon Smith static bool hasSelfReference(MDNode *N) {
75370de3240SKazu Hirata return llvm::is_contained(N->operands(), N);
7544ee4a98eSDuncan P. N. Exon Smith }
7554ee4a98eSDuncan P. N. Exon Smith
replaceWithPermanentImpl()7564ee4a98eSDuncan P. N. Exon Smith MDNode *MDNode::replaceWithPermanentImpl() {
75755ca964eSDuncan P. N. Exon Smith switch (getMetadataID()) {
75855ca964eSDuncan P. N. Exon Smith default:
75955ca964eSDuncan P. N. Exon Smith // If this type isn't uniquable, replace with a distinct node.
76055ca964eSDuncan P. N. Exon Smith return replaceWithDistinctImpl();
76155ca964eSDuncan P. N. Exon Smith
76255ca964eSDuncan P. N. Exon Smith #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
76355ca964eSDuncan P. N. Exon Smith case CLASS##Kind: \
76455ca964eSDuncan P. N. Exon Smith break;
76555ca964eSDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
76655ca964eSDuncan P. N. Exon Smith }
76755ca964eSDuncan P. N. Exon Smith
76855ca964eSDuncan P. N. Exon Smith // Even if this type is uniquable, self-references have to be distinct.
7694ee4a98eSDuncan P. N. Exon Smith if (hasSelfReference(this))
7704ee4a98eSDuncan P. N. Exon Smith return replaceWithDistinctImpl();
7714ee4a98eSDuncan P. N. Exon Smith return replaceWithUniquedImpl();
7724ee4a98eSDuncan P. N. Exon Smith }
7734ee4a98eSDuncan P. N. Exon Smith
replaceWithUniquedImpl()77486475292SDuncan P. N. Exon Smith MDNode *MDNode::replaceWithUniquedImpl() {
77586475292SDuncan P. N. Exon Smith // Try to uniquify in place.
77686475292SDuncan P. N. Exon Smith MDNode *UniquedNode = uniquify();
7774ee4a98eSDuncan P. N. Exon Smith
77886475292SDuncan P. N. Exon Smith if (UniquedNode == this) {
77986475292SDuncan P. N. Exon Smith makeUniqued();
78086475292SDuncan P. N. Exon Smith return this;
78186475292SDuncan P. N. Exon Smith }
78286475292SDuncan P. N. Exon Smith
78386475292SDuncan P. N. Exon Smith // Collision, so RAUW instead.
78486475292SDuncan P. N. Exon Smith replaceAllUsesWith(UniquedNode);
78586475292SDuncan P. N. Exon Smith deleteAsSubclass();
78686475292SDuncan P. N. Exon Smith return UniquedNode;
78786475292SDuncan P. N. Exon Smith }
78886475292SDuncan P. N. Exon Smith
replaceWithDistinctImpl()78986475292SDuncan P. N. Exon Smith MDNode *MDNode::replaceWithDistinctImpl() {
79086475292SDuncan P. N. Exon Smith makeDistinct();
79186475292SDuncan P. N. Exon Smith return this;
79286475292SDuncan P. N. Exon Smith }
79386475292SDuncan P. N. Exon Smith
recalculateHash()794118632dbSDuncan P. N. Exon Smith void MDTuple::recalculateHash() {
79593e983e7SDuncan P. N. Exon Smith setHash(MDTupleInfo::KeyTy::calculateHash(this));
796967629e1SDuncan P. N. Exon Smith }
797967629e1SDuncan P. N. Exon Smith
dropAllReferences()7985bf8fef5SDuncan P. N. Exon Smith void MDNode::dropAllReferences() {
7992740c187SWolfgang Pieb for (unsigned I = 0, E = getNumOperands(); I != E; ++I)
8005bf8fef5SDuncan P. N. Exon Smith setOperand(I, nullptr);
801fef609f1SDuncan P. N. Exon Smith if (Context.hasReplaceableUses()) {
8022bc00f4aSDuncan P. N. Exon Smith Context.getReplaceableUses()->resolveAllUses(/* ResolveUsers */ false);
8032bc00f4aSDuncan P. N. Exon Smith (void)Context.takeReplaceableUses();
804ef860a24SChandler Carruth }
805ef860a24SChandler Carruth }
806ef860a24SChandler Carruth
handleChangedOperand(void * Ref,Metadata * New)8072bc00f4aSDuncan P. N. Exon Smith void MDNode::handleChangedOperand(void *Ref, Metadata *New) {
8085bf8fef5SDuncan P. N. Exon Smith unsigned Op = static_cast<MDOperand *>(Ref) - op_begin();
8095bf8fef5SDuncan P. N. Exon Smith assert(Op < getNumOperands() && "Expected valid operand");
8105bf8fef5SDuncan P. N. Exon Smith
8113d580568SDuncan P. N. Exon Smith if (!isUniqued()) {
8125bf8fef5SDuncan P. N. Exon Smith // This node is not uniqued. Just set the operand and be done with it.
8135bf8fef5SDuncan P. N. Exon Smith setOperand(Op, New);
8145bf8fef5SDuncan P. N. Exon Smith return;
815ef860a24SChandler Carruth }
816ef860a24SChandler Carruth
817bf68e80dSDuncan P. N. Exon Smith // This node is uniqued.
818bf68e80dSDuncan P. N. Exon Smith eraseFromStore();
8195bf8fef5SDuncan P. N. Exon Smith
8205bf8fef5SDuncan P. N. Exon Smith Metadata *Old = getOperand(Op);
8215bf8fef5SDuncan P. N. Exon Smith setOperand(Op, New);
8225bf8fef5SDuncan P. N. Exon Smith
8239cbc69d1SDuncan P. N. Exon Smith // Drop uniquing for self-reference cycles and deleted constants.
8249cbc69d1SDuncan P. N. Exon Smith if (New == this || (!New && Old && isa<ConstantAsMetadata>(Old))) {
8255bf8fef5SDuncan P. N. Exon Smith if (!isResolved())
8265bf8fef5SDuncan P. N. Exon Smith resolve();
827f08b8b4bSDuncan P. N. Exon Smith storeDistinctInContext();
8285bf8fef5SDuncan P. N. Exon Smith return;
8295bf8fef5SDuncan P. N. Exon Smith }
8305bf8fef5SDuncan P. N. Exon Smith
8315bf8fef5SDuncan P. N. Exon Smith // Re-unique the node.
832bf68e80dSDuncan P. N. Exon Smith auto *Uniqued = uniquify();
833bf68e80dSDuncan P. N. Exon Smith if (Uniqued == this) {
8343a16d80aSDuncan P. N. Exon Smith if (!isResolved())
8353a16d80aSDuncan P. N. Exon Smith resolveAfterOperandChange(Old, New);
8365bf8fef5SDuncan P. N. Exon Smith return;
8375bf8fef5SDuncan P. N. Exon Smith }
8385bf8fef5SDuncan P. N. Exon Smith
8395bf8fef5SDuncan P. N. Exon Smith // Collision.
8405bf8fef5SDuncan P. N. Exon Smith if (!isResolved()) {
8415bf8fef5SDuncan P. N. Exon Smith // Still unresolved, so RAUW.
842d9e6eb71SDuncan P. N. Exon Smith //
843d9e6eb71SDuncan P. N. Exon Smith // First, clear out all operands to prevent any recursion (similar to
844d9e6eb71SDuncan P. N. Exon Smith // dropAllReferences(), but we still need the use-list).
845d9e6eb71SDuncan P. N. Exon Smith for (unsigned O = 0, E = getNumOperands(); O != E; ++O)
846d9e6eb71SDuncan P. N. Exon Smith setOperand(O, nullptr);
847fef609f1SDuncan P. N. Exon Smith if (Context.hasReplaceableUses())
8482711ca7cSDuncan P. N. Exon Smith Context.getReplaceableUses()->replaceAllUsesWith(Uniqued);
849bf68e80dSDuncan P. N. Exon Smith deleteAsSubclass();
8505bf8fef5SDuncan P. N. Exon Smith return;
8515bf8fef5SDuncan P. N. Exon Smith }
8525bf8fef5SDuncan P. N. Exon Smith
853d9e6eb71SDuncan P. N. Exon Smith // Store in non-uniqued form if RAUW isn't possible.
8545bf8fef5SDuncan P. N. Exon Smith storeDistinctInContext();
8555bf8fef5SDuncan P. N. Exon Smith }
8565bf8fef5SDuncan P. N. Exon Smith
deleteAsSubclass()8572bc00f4aSDuncan P. N. Exon Smith void MDNode::deleteAsSubclass() {
858bf68e80dSDuncan P. N. Exon Smith switch (getMetadataID()) {
859bf68e80dSDuncan P. N. Exon Smith default:
8602bc00f4aSDuncan P. N. Exon Smith llvm_unreachable("Invalid subclass of MDNode");
8612bc00f4aSDuncan P. N. Exon Smith #define HANDLE_MDNODE_LEAF(CLASS) \
862bf68e80dSDuncan P. N. Exon Smith case CLASS##Kind: \
863bf68e80dSDuncan P. N. Exon Smith delete cast<CLASS>(this); \
864bf68e80dSDuncan P. N. Exon Smith break;
865bf68e80dSDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
866bf68e80dSDuncan P. N. Exon Smith }
867bf68e80dSDuncan P. N. Exon Smith }
868bf68e80dSDuncan P. N. Exon Smith
869f9d1bc99SDuncan P. N. Exon Smith template <class T, class InfoT>
uniquifyImpl(T * N,DenseSet<T *,InfoT> & Store)870f9d1bc99SDuncan P. N. Exon Smith static T *uniquifyImpl(T *N, DenseSet<T *, InfoT> &Store) {
871f9d1bc99SDuncan P. N. Exon Smith if (T *U = getUniqued(Store, N))
872f9d1bc99SDuncan P. N. Exon Smith return U;
873f9d1bc99SDuncan P. N. Exon Smith
874f9d1bc99SDuncan P. N. Exon Smith Store.insert(N);
875f9d1bc99SDuncan P. N. Exon Smith return N;
876f9d1bc99SDuncan P. N. Exon Smith }
877f9d1bc99SDuncan P. N. Exon Smith
8780f529998SDuncan P. N. Exon Smith template <class NodeTy> struct MDNode::HasCachedHash {
879de6cce22SEugene Zelenko using Yes = char[1];
880de6cce22SEugene Zelenko using No = char[2];
8810f529998SDuncan P. N. Exon Smith template <class U, U Val> struct SFINAE {};
882f9d1bc99SDuncan P. N. Exon Smith
8830f529998SDuncan P. N. Exon Smith template <class U>
8840f529998SDuncan P. N. Exon Smith static Yes &check(SFINAE<void (U::*)(unsigned), &U::setHash> *);
8850f529998SDuncan P. N. Exon Smith template <class U> static No &check(...);
8860f529998SDuncan P. N. Exon Smith
8870f529998SDuncan P. N. Exon Smith static const bool value = sizeof(check<NodeTy>(nullptr)) == sizeof(Yes);
8880f529998SDuncan P. N. Exon Smith };
8890f529998SDuncan P. N. Exon Smith
uniquify()8900f529998SDuncan P. N. Exon Smith MDNode *MDNode::uniquify() {
8914ee4a98eSDuncan P. N. Exon Smith assert(!hasSelfReference(this) && "Cannot uniquify a self-referencing node");
8924ee4a98eSDuncan P. N. Exon Smith
893f9d1bc99SDuncan P. N. Exon Smith // Try to insert into uniquing store.
894bf68e80dSDuncan P. N. Exon Smith switch (getMetadataID()) {
895bf68e80dSDuncan P. N. Exon Smith default:
89655ca964eSDuncan P. N. Exon Smith llvm_unreachable("Invalid or non-uniquable subclass of MDNode");
89755ca964eSDuncan P. N. Exon Smith #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
8980f529998SDuncan P. N. Exon Smith case CLASS##Kind: { \
8990f529998SDuncan P. N. Exon Smith CLASS *SubclassThis = cast<CLASS>(this); \
9000f529998SDuncan P. N. Exon Smith std::integral_constant<bool, HasCachedHash<CLASS>::value> \
9010f529998SDuncan P. N. Exon Smith ShouldRecalculateHash; \
9020f529998SDuncan P. N. Exon Smith dispatchRecalculateHash(SubclassThis, ShouldRecalculateHash); \
9030f529998SDuncan P. N. Exon Smith return uniquifyImpl(SubclassThis, getContext().pImpl->CLASS##s); \
9040f529998SDuncan P. N. Exon Smith }
905bf68e80dSDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
906bf68e80dSDuncan P. N. Exon Smith }
907bf68e80dSDuncan P. N. Exon Smith }
908bf68e80dSDuncan P. N. Exon Smith
eraseFromStore()9092bc00f4aSDuncan P. N. Exon Smith void MDNode::eraseFromStore() {
910bf68e80dSDuncan P. N. Exon Smith switch (getMetadataID()) {
911bf68e80dSDuncan P. N. Exon Smith default:
91255ca964eSDuncan P. N. Exon Smith llvm_unreachable("Invalid or non-uniquable subclass of MDNode");
91355ca964eSDuncan P. N. Exon Smith #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
914bf68e80dSDuncan P. N. Exon Smith case CLASS##Kind: \
9156cf10d27SDuncan P. N. Exon Smith getContext().pImpl->CLASS##s.erase(cast<CLASS>(this)); \
916bf68e80dSDuncan P. N. Exon Smith break;
917bf68e80dSDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
918bf68e80dSDuncan P. N. Exon Smith }
919bf68e80dSDuncan P. N. Exon Smith }
920bf68e80dSDuncan P. N. Exon Smith
getImpl(LLVMContext & Context,ArrayRef<Metadata * > MDs,StorageType Storage,bool ShouldCreate)921ac3128d9SDuncan P. N. Exon Smith MDTuple *MDTuple::getImpl(LLVMContext &Context, ArrayRef<Metadata *> MDs,
9221b0064d0SDuncan P. N. Exon Smith StorageType Storage, bool ShouldCreate) {
9231b0064d0SDuncan P. N. Exon Smith unsigned Hash = 0;
9241b0064d0SDuncan P. N. Exon Smith if (Storage == Uniqued) {
925118632dbSDuncan P. N. Exon Smith MDTupleInfo::KeyTy Key(MDs);
926b57f9e97SDuncan P. N. Exon Smith if (auto *N = getUniqued(Context.pImpl->MDTuples, Key))
927b57f9e97SDuncan P. N. Exon Smith return N;
928ac3128d9SDuncan P. N. Exon Smith if (!ShouldCreate)
929f39c3b81SDuncan P. N. Exon Smith return nullptr;
93093e983e7SDuncan P. N. Exon Smith Hash = Key.getHash();
9311b0064d0SDuncan P. N. Exon Smith } else {
9321b0064d0SDuncan P. N. Exon Smith assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
933ef860a24SChandler Carruth }
934ef860a24SChandler Carruth
9352740c187SWolfgang Pieb return storeImpl(new (MDs.size(), Storage)
9362740c187SWolfgang Pieb MDTuple(Context, Storage, Hash, MDs),
9375b8c4401SDuncan P. N. Exon Smith Storage, Context.pImpl->MDTuples);
9385e5b8509SDuncan P. N. Exon Smith }
9395e5b8509SDuncan P. N. Exon Smith
deleteTemporary(MDNode * N)940946fdcc5SDuncan P. N. Exon Smith void MDNode::deleteTemporary(MDNode *N) {
941946fdcc5SDuncan P. N. Exon Smith assert(N->isTemporary() && "Expected temporary node");
9428d536973SDuncan P. N. Exon Smith N->replaceAllUsesWith(nullptr);
9432bc00f4aSDuncan P. N. Exon Smith N->deleteAsSubclass();
944ef860a24SChandler Carruth }
945ef860a24SChandler Carruth
storeDistinctInContext()9462bc00f4aSDuncan P. N. Exon Smith void MDNode::storeDistinctInContext() {
947fef609f1SDuncan P. N. Exon Smith assert(!Context.hasReplaceableUses() && "Unexpected replaceable uses");
9482740c187SWolfgang Pieb assert(!getNumUnresolved() && "Unexpected unresolved nodes");
949f1340453SDuncan P. N. Exon Smith Storage = Distinct;
950fef609f1SDuncan P. N. Exon Smith assert(isResolved() && "Expected this to be resolved");
9510f529998SDuncan P. N. Exon Smith
9520f529998SDuncan P. N. Exon Smith // Reset the hash.
9530f529998SDuncan P. N. Exon Smith switch (getMetadataID()) {
9540f529998SDuncan P. N. Exon Smith default:
9550f529998SDuncan P. N. Exon Smith llvm_unreachable("Invalid subclass of MDNode");
9560f529998SDuncan P. N. Exon Smith #define HANDLE_MDNODE_LEAF(CLASS) \
9570f529998SDuncan P. N. Exon Smith case CLASS##Kind: { \
9580f529998SDuncan P. N. Exon Smith std::integral_constant<bool, HasCachedHash<CLASS>::value> ShouldResetHash; \
9590f529998SDuncan P. N. Exon Smith dispatchResetHash(cast<CLASS>(this), ShouldResetHash); \
9600f529998SDuncan P. N. Exon Smith break; \
9610f529998SDuncan P. N. Exon Smith }
9620f529998SDuncan P. N. Exon Smith #include "llvm/IR/Metadata.def"
9630f529998SDuncan P. N. Exon Smith }
9640f529998SDuncan P. N. Exon Smith
9653eef9d18SDuncan P. N. Exon Smith getContext().pImpl->DistinctMDNodes.push_back(this);
966ef860a24SChandler Carruth }
967ef860a24SChandler Carruth
replaceOperandWith(unsigned I,Metadata * New)9685bf8fef5SDuncan P. N. Exon Smith void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
9695bf8fef5SDuncan P. N. Exon Smith if (getOperand(I) == New)
970ef860a24SChandler Carruth return;
971ef860a24SChandler Carruth
972de03a8b3SDuncan P. N. Exon Smith if (!isUniqued()) {
973daa335a9SDuncan P. N. Exon Smith setOperand(I, New);
974f39c3b81SDuncan P. N. Exon Smith return;
975f39c3b81SDuncan P. N. Exon Smith }
976ef860a24SChandler Carruth
9772bc00f4aSDuncan P. N. Exon Smith handleChangedOperand(mutable_begin() + I, New);
978ef860a24SChandler Carruth }
979ef860a24SChandler Carruth
setOperand(unsigned I,Metadata * New)9805bf8fef5SDuncan P. N. Exon Smith void MDNode::setOperand(unsigned I, Metadata *New) {
9812740c187SWolfgang Pieb assert(I < getNumOperands());
982efdf285bSDuncan P. N. Exon Smith mutable_begin()[I].reset(New, isUniqued() ? this : nullptr);
983ef860a24SChandler Carruth }
984ef860a24SChandler Carruth
9859da9c766SSanjay Patel /// Get a node or a self-reference that looks like it.
9869c51b50aSDuncan P. N. Exon Smith ///
9879c51b50aSDuncan P. N. Exon Smith /// Special handling for finding self-references, for use by \a
9889c51b50aSDuncan P. N. Exon Smith /// MDNode::concatenate() and \a MDNode::intersect() to maintain behaviour from
9899c51b50aSDuncan P. N. Exon Smith /// when self-referencing nodes were still uniqued. If the first operand has
9909c51b50aSDuncan P. N. Exon Smith /// the same operands as \c Ops, return the first operand instead.
getOrSelfReference(LLVMContext & Context,ArrayRef<Metadata * > Ops)9915bf8fef5SDuncan P. N. Exon Smith static MDNode *getOrSelfReference(LLVMContext &Context,
9925bf8fef5SDuncan P. N. Exon Smith ArrayRef<Metadata *> Ops) {
9939c51b50aSDuncan P. N. Exon Smith if (!Ops.empty())
9949c51b50aSDuncan P. N. Exon Smith if (MDNode *N = dyn_cast_or_null<MDNode>(Ops[0]))
9959c51b50aSDuncan P. N. Exon Smith if (N->getNumOperands() == Ops.size() && N == N->getOperand(0)) {
9969c51b50aSDuncan P. N. Exon Smith for (unsigned I = 1, E = Ops.size(); I != E; ++I)
9979c51b50aSDuncan P. N. Exon Smith if (Ops[I] != N->getOperand(I))
9989c51b50aSDuncan P. N. Exon Smith return MDNode::get(Context, Ops);
9999c51b50aSDuncan P. N. Exon Smith return N;
10009c51b50aSDuncan P. N. Exon Smith }
10019c51b50aSDuncan P. N. Exon Smith
10029c51b50aSDuncan P. N. Exon Smith return MDNode::get(Context, Ops);
10039c51b50aSDuncan P. N. Exon Smith }
10049c51b50aSDuncan P. N. Exon Smith
concatenate(MDNode * A,MDNode * B)10059414665aSHal Finkel MDNode *MDNode::concatenate(MDNode *A, MDNode *B) {
10069414665aSHal Finkel if (!A)
10079414665aSHal Finkel return B;
10089414665aSHal Finkel if (!B)
10099414665aSHal Finkel return A;
10109414665aSHal Finkel
1011fa0f1e66SDavid Majnemer SmallSetVector<Metadata *, 4> MDs(A->op_begin(), A->op_end());
1012fa0f1e66SDavid Majnemer MDs.insert(B->op_begin(), B->op_end());
10139414665aSHal Finkel
10149c51b50aSDuncan P. N. Exon Smith // FIXME: This preserves long-standing behaviour, but is it really the right
10159c51b50aSDuncan P. N. Exon Smith // behaviour? Or was that an unintended side-effect of node uniquing?
1016fa0f1e66SDavid Majnemer return getOrSelfReference(A->getContext(), MDs.getArrayRef());
10179414665aSHal Finkel }
10189414665aSHal Finkel
intersect(MDNode * A,MDNode * B)10199414665aSHal Finkel MDNode *MDNode::intersect(MDNode *A, MDNode *B) {
10209414665aSHal Finkel if (!A || !B)
10219414665aSHal Finkel return nullptr;
10229414665aSHal Finkel
102300940fb8SDavid Majnemer SmallSetVector<Metadata *, 4> MDs(A->op_begin(), A->op_end());
102400940fb8SDavid Majnemer SmallPtrSet<Metadata *, 4> BSet(B->op_begin(), B->op_end());
10259c52422cSNikita Popov MDs.remove_if([&](Metadata *MD) { return !BSet.count(MD); });
10269414665aSHal Finkel
1027ac8ee289SDuncan P. N. Exon Smith // FIXME: This preserves long-standing behaviour, but is it really the right
1028ac8ee289SDuncan P. N. Exon Smith // behaviour? Or was that an unintended side-effect of node uniquing?
102900940fb8SDavid Majnemer return getOrSelfReference(A->getContext(), MDs.getArrayRef());
10309414665aSHal Finkel }
10319414665aSHal Finkel
getMostGenericAliasScope(MDNode * A,MDNode * B)10325ec75227SBjorn Steinbrink MDNode *MDNode::getMostGenericAliasScope(MDNode *A, MDNode *B) {
10335ec75227SBjorn Steinbrink if (!A || !B)
10345ec75227SBjorn Steinbrink return nullptr;
10355ec75227SBjorn Steinbrink
103618603319Smodimo // Take the intersection of domains then union the scopes
103718603319Smodimo // within those domains
103818603319Smodimo SmallPtrSet<const MDNode *, 16> ADomains;
103918603319Smodimo SmallPtrSet<const MDNode *, 16> IntersectDomains;
104018603319Smodimo SmallSetVector<Metadata *, 4> MDs;
104118603319Smodimo for (const MDOperand &MDOp : A->operands())
104218603319Smodimo if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
104318603319Smodimo if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
104418603319Smodimo ADomains.insert(Domain);
104518603319Smodimo
104618603319Smodimo for (const MDOperand &MDOp : B->operands())
104718603319Smodimo if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
104818603319Smodimo if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
104918603319Smodimo if (ADomains.contains(Domain)) {
105018603319Smodimo IntersectDomains.insert(Domain);
105118603319Smodimo MDs.insert(MDOp);
105218603319Smodimo }
105318603319Smodimo
105418603319Smodimo for (const MDOperand &MDOp : A->operands())
105518603319Smodimo if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
105618603319Smodimo if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
105718603319Smodimo if (IntersectDomains.contains(Domain))
105818603319Smodimo MDs.insert(MDOp);
105918603319Smodimo
106018603319Smodimo return MDs.empty() ? nullptr
106118603319Smodimo : getOrSelfReference(A->getContext(), MDs.getArrayRef());
10625ec75227SBjorn Steinbrink }
10635ec75227SBjorn Steinbrink
getMostGenericFPMath(MDNode * A,MDNode * B)1064ef860a24SChandler Carruth MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) {
1065ef860a24SChandler Carruth if (!A || !B)
1066c620761cSCraig Topper return nullptr;
1067ef860a24SChandler Carruth
10685bf8fef5SDuncan P. N. Exon Smith APFloat AVal = mdconst::extract<ConstantFP>(A->getOperand(0))->getValueAPF();
10695bf8fef5SDuncan P. N. Exon Smith APFloat BVal = mdconst::extract<ConstantFP>(B->getOperand(0))->getValueAPF();
107011d1573bSJay Foad if (AVal < BVal)
1071ef860a24SChandler Carruth return A;
1072ef860a24SChandler Carruth return B;
1073ef860a24SChandler Carruth }
1074ef860a24SChandler Carruth
isContiguous(const ConstantRange & A,const ConstantRange & B)1075ef860a24SChandler Carruth static bool isContiguous(const ConstantRange &A, const ConstantRange &B) {
1076ef860a24SChandler Carruth return A.getUpper() == B.getLower() || A.getLower() == B.getUpper();
1077ef860a24SChandler Carruth }
1078ef860a24SChandler Carruth
canBeMerged(const ConstantRange & A,const ConstantRange & B)1079ef860a24SChandler Carruth static bool canBeMerged(const ConstantRange &A, const ConstantRange &B) {
1080ef860a24SChandler Carruth return !A.intersectWith(B).isEmptySet() || isContiguous(A, B);
1081ef860a24SChandler Carruth }
1082ef860a24SChandler Carruth
tryMergeRange(SmallVectorImpl<ConstantInt * > & EndPoints,ConstantInt * Low,ConstantInt * High)10835bf8fef5SDuncan P. N. Exon Smith static bool tryMergeRange(SmallVectorImpl<ConstantInt *> &EndPoints,
10845bf8fef5SDuncan P. N. Exon Smith ConstantInt *Low, ConstantInt *High) {
1085ef860a24SChandler Carruth ConstantRange NewRange(Low->getValue(), High->getValue());
1086ef860a24SChandler Carruth unsigned Size = EndPoints.size();
10875bf8fef5SDuncan P. N. Exon Smith APInt LB = EndPoints[Size - 2]->getValue();
10885bf8fef5SDuncan P. N. Exon Smith APInt LE = EndPoints[Size - 1]->getValue();
1089ef860a24SChandler Carruth ConstantRange LastRange(LB, LE);
1090ef860a24SChandler Carruth if (canBeMerged(NewRange, LastRange)) {
1091ef860a24SChandler Carruth ConstantRange Union = LastRange.unionWith(NewRange);
1092ef860a24SChandler Carruth Type *Ty = High->getType();
10935bf8fef5SDuncan P. N. Exon Smith EndPoints[Size - 2] =
10945bf8fef5SDuncan P. N. Exon Smith cast<ConstantInt>(ConstantInt::get(Ty, Union.getLower()));
10955bf8fef5SDuncan P. N. Exon Smith EndPoints[Size - 1] =
10965bf8fef5SDuncan P. N. Exon Smith cast<ConstantInt>(ConstantInt::get(Ty, Union.getUpper()));
1097ef860a24SChandler Carruth return true;
1098ef860a24SChandler Carruth }
1099ef860a24SChandler Carruth return false;
1100ef860a24SChandler Carruth }
1101ef860a24SChandler Carruth
addRange(SmallVectorImpl<ConstantInt * > & EndPoints,ConstantInt * Low,ConstantInt * High)11025bf8fef5SDuncan P. N. Exon Smith static void addRange(SmallVectorImpl<ConstantInt *> &EndPoints,
11035bf8fef5SDuncan P. N. Exon Smith ConstantInt *Low, ConstantInt *High) {
1104ef860a24SChandler Carruth if (!EndPoints.empty())
1105ef860a24SChandler Carruth if (tryMergeRange(EndPoints, Low, High))
1106ef860a24SChandler Carruth return;
1107ef860a24SChandler Carruth
1108ef860a24SChandler Carruth EndPoints.push_back(Low);
1109ef860a24SChandler Carruth EndPoints.push_back(High);
1110ef860a24SChandler Carruth }
1111ef860a24SChandler Carruth
getMostGenericRange(MDNode * A,MDNode * B)1112ef860a24SChandler Carruth MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
1113ef860a24SChandler Carruth // Given two ranges, we want to compute the union of the ranges. This
1114abd6b1dcSCraig Topper // is slightly complicated by having to combine the intervals and merge
1115ef860a24SChandler Carruth // the ones that overlap.
1116ef860a24SChandler Carruth
1117ef860a24SChandler Carruth if (!A || !B)
1118c620761cSCraig Topper return nullptr;
1119ef860a24SChandler Carruth
1120ef860a24SChandler Carruth if (A == B)
1121ef860a24SChandler Carruth return A;
1122ef860a24SChandler Carruth
1123abd6b1dcSCraig Topper // First, walk both lists in order of the lower boundary of each interval.
1124ef860a24SChandler Carruth // At each step, try to merge the new interval to the last one we adedd.
11255bf8fef5SDuncan P. N. Exon Smith SmallVector<ConstantInt *, 4> EndPoints;
1126ef860a24SChandler Carruth int AI = 0;
1127ef860a24SChandler Carruth int BI = 0;
1128ef860a24SChandler Carruth int AN = A->getNumOperands() / 2;
1129ef860a24SChandler Carruth int BN = B->getNumOperands() / 2;
1130ef860a24SChandler Carruth while (AI < AN && BI < BN) {
11315bf8fef5SDuncan P. N. Exon Smith ConstantInt *ALow = mdconst::extract<ConstantInt>(A->getOperand(2 * AI));
11325bf8fef5SDuncan P. N. Exon Smith ConstantInt *BLow = mdconst::extract<ConstantInt>(B->getOperand(2 * BI));
1133ef860a24SChandler Carruth
1134ef860a24SChandler Carruth if (ALow->getValue().slt(BLow->getValue())) {
11355bf8fef5SDuncan P. N. Exon Smith addRange(EndPoints, ALow,
11365bf8fef5SDuncan P. N. Exon Smith mdconst::extract<ConstantInt>(A->getOperand(2 * AI + 1)));
1137ef860a24SChandler Carruth ++AI;
1138ef860a24SChandler Carruth } else {
11395bf8fef5SDuncan P. N. Exon Smith addRange(EndPoints, BLow,
11405bf8fef5SDuncan P. N. Exon Smith mdconst::extract<ConstantInt>(B->getOperand(2 * BI + 1)));
1141ef860a24SChandler Carruth ++BI;
1142ef860a24SChandler Carruth }
1143ef860a24SChandler Carruth }
1144ef860a24SChandler Carruth while (AI < AN) {
11455bf8fef5SDuncan P. N. Exon Smith addRange(EndPoints, mdconst::extract<ConstantInt>(A->getOperand(2 * AI)),
11465bf8fef5SDuncan P. N. Exon Smith mdconst::extract<ConstantInt>(A->getOperand(2 * AI + 1)));
1147ef860a24SChandler Carruth ++AI;
1148ef860a24SChandler Carruth }
1149ef860a24SChandler Carruth while (BI < BN) {
11505bf8fef5SDuncan P. N. Exon Smith addRange(EndPoints, mdconst::extract<ConstantInt>(B->getOperand(2 * BI)),
11515bf8fef5SDuncan P. N. Exon Smith mdconst::extract<ConstantInt>(B->getOperand(2 * BI + 1)));
1152ef860a24SChandler Carruth ++BI;
1153ef860a24SChandler Carruth }
1154ef860a24SChandler Carruth
1155ef860a24SChandler Carruth // If we have more than 2 ranges (4 endpoints) we have to try to merge
1156ef860a24SChandler Carruth // the last and first ones.
1157ef860a24SChandler Carruth unsigned Size = EndPoints.size();
1158ef860a24SChandler Carruth if (Size > 4) {
11595bf8fef5SDuncan P. N. Exon Smith ConstantInt *FB = EndPoints[0];
11605bf8fef5SDuncan P. N. Exon Smith ConstantInt *FE = EndPoints[1];
1161ef860a24SChandler Carruth if (tryMergeRange(EndPoints, FB, FE)) {
1162ef860a24SChandler Carruth for (unsigned i = 0; i < Size - 2; ++i) {
1163ef860a24SChandler Carruth EndPoints[i] = EndPoints[i + 2];
1164ef860a24SChandler Carruth }
1165ef860a24SChandler Carruth EndPoints.resize(Size - 2);
1166ef860a24SChandler Carruth }
1167ef860a24SChandler Carruth }
1168ef860a24SChandler Carruth
1169ef860a24SChandler Carruth // If in the end we have a single range, it is possible that it is now the
1170ef860a24SChandler Carruth // full range. Just drop the metadata in that case.
1171ef860a24SChandler Carruth if (EndPoints.size() == 2) {
11725bf8fef5SDuncan P. N. Exon Smith ConstantRange Range(EndPoints[0]->getValue(), EndPoints[1]->getValue());
1173ef860a24SChandler Carruth if (Range.isFullSet())
1174c620761cSCraig Topper return nullptr;
1175ef860a24SChandler Carruth }
1176ef860a24SChandler Carruth
11775bf8fef5SDuncan P. N. Exon Smith SmallVector<Metadata *, 4> MDs;
11785bf8fef5SDuncan P. N. Exon Smith MDs.reserve(EndPoints.size());
11795bf8fef5SDuncan P. N. Exon Smith for (auto *I : EndPoints)
11805bf8fef5SDuncan P. N. Exon Smith MDs.push_back(ConstantAsMetadata::get(I));
11815bf8fef5SDuncan P. N. Exon Smith return MDNode::get(A->getContext(), MDs);
1182ef860a24SChandler Carruth }
1183ef860a24SChandler Carruth
getMostGenericAlignmentOrDereferenceable(MDNode * A,MDNode * B)11845c5011d5SArtur Pilipenko MDNode *MDNode::getMostGenericAlignmentOrDereferenceable(MDNode *A, MDNode *B) {
11855c5011d5SArtur Pilipenko if (!A || !B)
11865c5011d5SArtur Pilipenko return nullptr;
11875c5011d5SArtur Pilipenko
11885c5011d5SArtur Pilipenko ConstantInt *AVal = mdconst::extract<ConstantInt>(A->getOperand(0));
11895c5011d5SArtur Pilipenko ConstantInt *BVal = mdconst::extract<ConstantInt>(B->getOperand(0));
11905c5011d5SArtur Pilipenko if (AVal->getZExtValue() < BVal->getZExtValue())
11915c5011d5SArtur Pilipenko return A;
11925c5011d5SArtur Pilipenko return B;
11935c5011d5SArtur Pilipenko }
11945c5011d5SArtur Pilipenko
1195ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
1196ef860a24SChandler Carruth // NamedMDNode implementation.
1197ef860a24SChandler Carruth //
1198ef860a24SChandler Carruth
getNMDOps(void * Operands)11995bf8fef5SDuncan P. N. Exon Smith static SmallVector<TrackingMDRef, 4> &getNMDOps(void *Operands) {
12005bf8fef5SDuncan P. N. Exon Smith return *(SmallVector<TrackingMDRef, 4> *)Operands;
1201ef860a24SChandler Carruth }
1202ef860a24SChandler Carruth
NamedMDNode(const Twine & N)1203ef860a24SChandler Carruth NamedMDNode::NamedMDNode(const Twine &N)
1204deaf6951SEugene Zelenko : Name(N.str()), Operands(new SmallVector<TrackingMDRef, 4>()) {}
1205ef860a24SChandler Carruth
~NamedMDNode()1206ef860a24SChandler Carruth NamedMDNode::~NamedMDNode() {
1207ef860a24SChandler Carruth dropAllReferences();
1208ef860a24SChandler Carruth delete &getNMDOps(Operands);
1209ef860a24SChandler Carruth }
1210ef860a24SChandler Carruth
getNumOperands() const1211ef860a24SChandler Carruth unsigned NamedMDNode::getNumOperands() const {
1212ef860a24SChandler Carruth return (unsigned)getNMDOps(Operands).size();
1213ef860a24SChandler Carruth }
1214ef860a24SChandler Carruth
getOperand(unsigned i) const1215de36e804SDuncan P. N. Exon Smith MDNode *NamedMDNode::getOperand(unsigned i) const {
1216ef860a24SChandler Carruth assert(i < getNumOperands() && "Invalid Operand number!");
12175bf8fef5SDuncan P. N. Exon Smith auto *N = getNMDOps(Operands)[i].get();
12185bf8fef5SDuncan P. N. Exon Smith return cast_or_null<MDNode>(N);
1219ef860a24SChandler Carruth }
1220ef860a24SChandler Carruth
addOperand(MDNode * M)12215bf8fef5SDuncan P. N. Exon Smith void NamedMDNode::addOperand(MDNode *M) { getNMDOps(Operands).emplace_back(M); }
1222ef860a24SChandler Carruth
setOperand(unsigned I,MDNode * New)1223df55d8baSDuncan P. N. Exon Smith void NamedMDNode::setOperand(unsigned I, MDNode *New) {
1224df55d8baSDuncan P. N. Exon Smith assert(I < getNumOperands() && "Invalid operand number");
1225df55d8baSDuncan P. N. Exon Smith getNMDOps(Operands)[I].reset(New);
1226df55d8baSDuncan P. N. Exon Smith }
1227df55d8baSDuncan P. N. Exon Smith
eraseFromParent()1228e0e0ed13SDehao Chen void NamedMDNode::eraseFromParent() { getParent()->eraseNamedMetadata(this); }
1229ef860a24SChandler Carruth
clearOperands()1230e5428043SMichael Ilseman void NamedMDNode::clearOperands() { getNMDOps(Operands).clear(); }
1231ef860a24SChandler Carruth
getName() const1232e0e0ed13SDehao Chen StringRef NamedMDNode::getName() const { return StringRef(Name); }
1233ef860a24SChandler Carruth
1234ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
1235ef860a24SChandler Carruth // Instruction Metadata method implementations.
1236ef860a24SChandler Carruth //
1237cbc28dc5SDuncan P. N. Exon Smith
lookup(unsigned ID) const12387975b8c3SSerge Pavlov MDNode *MDAttachments::lookup(unsigned ID) const {
12390deb9a9aSBenjamin Kramer for (const auto &A : Attachments)
12400deb9a9aSBenjamin Kramer if (A.MDKind == ID)
12410deb9a9aSBenjamin Kramer return A.Node;
12420deb9a9aSBenjamin Kramer return nullptr;
12430deb9a9aSBenjamin Kramer }
12440deb9a9aSBenjamin Kramer
get(unsigned ID,SmallVectorImpl<MDNode * > & Result) const12457975b8c3SSerge Pavlov void MDAttachments::get(unsigned ID, SmallVectorImpl<MDNode *> &Result) const {
12460deb9a9aSBenjamin Kramer for (const auto &A : Attachments)
1247382d81caSPeter Collingbourne if (A.MDKind == ID)
1248382d81caSPeter Collingbourne Result.push_back(A.Node);
1249382d81caSPeter Collingbourne }
1250382d81caSPeter Collingbourne
getAll(SmallVectorImpl<std::pair<unsigned,MDNode * >> & Result) const12517975b8c3SSerge Pavlov void MDAttachments::getAll(
12527975b8c3SSerge Pavlov SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const {
12537975b8c3SSerge Pavlov for (const auto &A : Attachments)
12547975b8c3SSerge Pavlov Result.emplace_back(A.MDKind, A.Node);
12557975b8c3SSerge Pavlov
12567975b8c3SSerge Pavlov // Sort the resulting array so it is stable with respect to metadata IDs. We
12577975b8c3SSerge Pavlov // need to preserve the original insertion order though.
12587975b8c3SSerge Pavlov if (Result.size() > 1)
12597975b8c3SSerge Pavlov llvm::stable_sort(Result, less_first());
12607975b8c3SSerge Pavlov }
12617975b8c3SSerge Pavlov
set(unsigned ID,MDNode * MD)12627975b8c3SSerge Pavlov void MDAttachments::set(unsigned ID, MDNode *MD) {
12637975b8c3SSerge Pavlov erase(ID);
12647975b8c3SSerge Pavlov if (MD)
12657975b8c3SSerge Pavlov insert(ID, *MD);
12667975b8c3SSerge Pavlov }
12677975b8c3SSerge Pavlov
insert(unsigned ID,MDNode & MD)12687975b8c3SSerge Pavlov void MDAttachments::insert(unsigned ID, MDNode &MD) {
12697975b8c3SSerge Pavlov Attachments.push_back({ID, TrackingMDNodeRef(&MD)});
12707975b8c3SSerge Pavlov }
12717975b8c3SSerge Pavlov
erase(unsigned ID)12727975b8c3SSerge Pavlov bool MDAttachments::erase(unsigned ID) {
12737975b8c3SSerge Pavlov if (empty())
12747975b8c3SSerge Pavlov return false;
12757975b8c3SSerge Pavlov
12767975b8c3SSerge Pavlov // Common case is one value.
12777975b8c3SSerge Pavlov if (Attachments.size() == 1 && Attachments.back().MDKind == ID) {
12787975b8c3SSerge Pavlov Attachments.pop_back();
12797975b8c3SSerge Pavlov return true;
12807975b8c3SSerge Pavlov }
12817975b8c3SSerge Pavlov
12823285ee14SKazu Hirata auto OldSize = Attachments.size();
12833285ee14SKazu Hirata llvm::erase_if(Attachments,
12840deb9a9aSBenjamin Kramer [ID](const Attachment &A) { return A.MDKind == ID; });
12853285ee14SKazu Hirata return OldSize != Attachments.size();
1286382d81caSPeter Collingbourne }
1287382d81caSPeter Collingbourne
getMetadata(unsigned KindID) const12887975b8c3SSerge Pavlov MDNode *Value::getMetadata(unsigned KindID) const {
12897975b8c3SSerge Pavlov if (!hasMetadata())
12907975b8c3SSerge Pavlov return nullptr;
12917975b8c3SSerge Pavlov const auto &Info = getContext().pImpl->ValueMetadata[this];
12927975b8c3SSerge Pavlov assert(!Info.empty() && "bit out of sync with hash table");
12937975b8c3SSerge Pavlov return Info.lookup(KindID);
12947975b8c3SSerge Pavlov }
1295382d81caSPeter Collingbourne
getMetadata(StringRef Kind) const12967975b8c3SSerge Pavlov MDNode *Value::getMetadata(StringRef Kind) const {
12977975b8c3SSerge Pavlov if (!hasMetadata())
12987975b8c3SSerge Pavlov return nullptr;
12997975b8c3SSerge Pavlov const auto &Info = getContext().pImpl->ValueMetadata[this];
13007975b8c3SSerge Pavlov assert(!Info.empty() && "bit out of sync with hash table");
13017975b8c3SSerge Pavlov return Info.lookup(getContext().getMDKindID(Kind));
13027975b8c3SSerge Pavlov }
13037975b8c3SSerge Pavlov
getMetadata(unsigned KindID,SmallVectorImpl<MDNode * > & MDs) const13047975b8c3SSerge Pavlov void Value::getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const {
13057975b8c3SSerge Pavlov if (hasMetadata())
13067975b8c3SSerge Pavlov getContext().pImpl->ValueMetadata[this].get(KindID, MDs);
13077975b8c3SSerge Pavlov }
13087975b8c3SSerge Pavlov
getMetadata(StringRef Kind,SmallVectorImpl<MDNode * > & MDs) const13097975b8c3SSerge Pavlov void Value::getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const {
13107975b8c3SSerge Pavlov if (hasMetadata())
13117975b8c3SSerge Pavlov getMetadata(getContext().getMDKindID(Kind), MDs);
13127975b8c3SSerge Pavlov }
13137975b8c3SSerge Pavlov
getAllMetadata(SmallVectorImpl<std::pair<unsigned,MDNode * >> & MDs) const13147975b8c3SSerge Pavlov void Value::getAllMetadata(
13157975b8c3SSerge Pavlov SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const {
13167975b8c3SSerge Pavlov if (hasMetadata()) {
13177975b8c3SSerge Pavlov assert(getContext().pImpl->ValueMetadata.count(this) &&
13187975b8c3SSerge Pavlov "bit out of sync with hash table");
13197975b8c3SSerge Pavlov const auto &Info = getContext().pImpl->ValueMetadata.find(this)->second;
13207975b8c3SSerge Pavlov assert(!Info.empty() && "Shouldn't have called this");
13217975b8c3SSerge Pavlov Info.getAll(MDs);
13227975b8c3SSerge Pavlov }
13237975b8c3SSerge Pavlov }
13247975b8c3SSerge Pavlov
setMetadata(unsigned KindID,MDNode * Node)13257975b8c3SSerge Pavlov void Value::setMetadata(unsigned KindID, MDNode *Node) {
13267975b8c3SSerge Pavlov assert(isa<Instruction>(this) || isa<GlobalObject>(this));
13277975b8c3SSerge Pavlov
13287975b8c3SSerge Pavlov // Handle the case when we're adding/updating metadata on a value.
13297975b8c3SSerge Pavlov if (Node) {
13307975b8c3SSerge Pavlov auto &Info = getContext().pImpl->ValueMetadata[this];
13317975b8c3SSerge Pavlov assert(!Info.empty() == HasMetadata && "bit out of sync with hash table");
13327975b8c3SSerge Pavlov if (Info.empty())
13337975b8c3SSerge Pavlov HasMetadata = true;
13347975b8c3SSerge Pavlov Info.set(KindID, Node);
13357975b8c3SSerge Pavlov return;
13367975b8c3SSerge Pavlov }
13377975b8c3SSerge Pavlov
13387975b8c3SSerge Pavlov // Otherwise, we're removing metadata from an instruction.
13397975b8c3SSerge Pavlov assert((HasMetadata == (getContext().pImpl->ValueMetadata.count(this) > 0)) &&
13407975b8c3SSerge Pavlov "bit out of sync with hash table");
13417975b8c3SSerge Pavlov if (!HasMetadata)
13427975b8c3SSerge Pavlov return; // Nothing to remove!
13437975b8c3SSerge Pavlov auto &Info = getContext().pImpl->ValueMetadata[this];
13447975b8c3SSerge Pavlov
13457975b8c3SSerge Pavlov // Handle removal of an existing value.
13467975b8c3SSerge Pavlov Info.erase(KindID);
13477975b8c3SSerge Pavlov if (!Info.empty())
13487975b8c3SSerge Pavlov return;
13497975b8c3SSerge Pavlov getContext().pImpl->ValueMetadata.erase(this);
13507975b8c3SSerge Pavlov HasMetadata = false;
13517975b8c3SSerge Pavlov }
13527975b8c3SSerge Pavlov
setMetadata(StringRef Kind,MDNode * Node)13537975b8c3SSerge Pavlov void Value::setMetadata(StringRef Kind, MDNode *Node) {
13547975b8c3SSerge Pavlov if (!Node && !HasMetadata)
13557975b8c3SSerge Pavlov return;
13567975b8c3SSerge Pavlov setMetadata(getContext().getMDKindID(Kind), Node);
13577975b8c3SSerge Pavlov }
13587975b8c3SSerge Pavlov
addMetadata(unsigned KindID,MDNode & MD)13597975b8c3SSerge Pavlov void Value::addMetadata(unsigned KindID, MDNode &MD) {
13607975b8c3SSerge Pavlov assert(isa<Instruction>(this) || isa<GlobalObject>(this));
13617975b8c3SSerge Pavlov if (!HasMetadata)
13627975b8c3SSerge Pavlov HasMetadata = true;
13637975b8c3SSerge Pavlov getContext().pImpl->ValueMetadata[this].insert(KindID, MD);
13647975b8c3SSerge Pavlov }
13657975b8c3SSerge Pavlov
addMetadata(StringRef Kind,MDNode & MD)13667975b8c3SSerge Pavlov void Value::addMetadata(StringRef Kind, MDNode &MD) {
13677975b8c3SSerge Pavlov addMetadata(getContext().getMDKindID(Kind), MD);
13687975b8c3SSerge Pavlov }
13697975b8c3SSerge Pavlov
eraseMetadata(unsigned KindID)13707975b8c3SSerge Pavlov bool Value::eraseMetadata(unsigned KindID) {
13717975b8c3SSerge Pavlov // Nothing to unset.
13727975b8c3SSerge Pavlov if (!HasMetadata)
13737975b8c3SSerge Pavlov return false;
13747975b8c3SSerge Pavlov
13757975b8c3SSerge Pavlov auto &Store = getContext().pImpl->ValueMetadata[this];
13767975b8c3SSerge Pavlov bool Changed = Store.erase(KindID);
13777975b8c3SSerge Pavlov if (Store.empty())
13787975b8c3SSerge Pavlov clearMetadata();
13797975b8c3SSerge Pavlov return Changed;
13807975b8c3SSerge Pavlov }
13817975b8c3SSerge Pavlov
clearMetadata()13827975b8c3SSerge Pavlov void Value::clearMetadata() {
13837975b8c3SSerge Pavlov if (!HasMetadata)
13847975b8c3SSerge Pavlov return;
13857975b8c3SSerge Pavlov assert(getContext().pImpl->ValueMetadata.count(this) &&
13867975b8c3SSerge Pavlov "bit out of sync with hash table");
13877975b8c3SSerge Pavlov getContext().pImpl->ValueMetadata.erase(this);
13887975b8c3SSerge Pavlov HasMetadata = false;
1389382d81caSPeter Collingbourne }
1390382d81caSPeter Collingbourne
setMetadata(StringRef Kind,MDNode * Node)1391de36e804SDuncan P. N. Exon Smith void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
1392de36e804SDuncan P. N. Exon Smith if (!Node && !hasMetadata())
1393de36e804SDuncan P. N. Exon Smith return;
1394de36e804SDuncan P. N. Exon Smith setMetadata(getContext().getMDKindID(Kind), Node);
1395ef860a24SChandler Carruth }
1396ef860a24SChandler Carruth
getMetadataImpl(StringRef Kind) const1397de36e804SDuncan P. N. Exon Smith MDNode *Instruction::getMetadataImpl(StringRef Kind) const {
1398ef860a24SChandler Carruth return getMetadataImpl(getContext().getMDKindID(Kind));
1399ef860a24SChandler Carruth }
1400ef860a24SChandler Carruth
dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs)1401cbdfdb74SAdrian Prantl void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) {
14027975b8c3SSerge Pavlov if (!Value::hasMetadata())
1403ab73c493SRafael Espindola return; // Nothing to remove!
1404ab73c493SRafael Espindola
14057975b8c3SSerge Pavlov if (KnownIDs.empty()) {
1406ab73c493SRafael Espindola // Just drop our entry at the store.
14077975b8c3SSerge Pavlov clearMetadata();
1408ab73c493SRafael Espindola return;
1409ab73c493SRafael Espindola }
1410ab73c493SRafael Espindola
14117975b8c3SSerge Pavlov SmallSet<unsigned, 4> KnownSet;
14127975b8c3SSerge Pavlov KnownSet.insert(KnownIDs.begin(), KnownIDs.end());
14137975b8c3SSerge Pavlov
14147975b8c3SSerge Pavlov auto &MetadataStore = getContext().pImpl->ValueMetadata;
14157975b8c3SSerge Pavlov auto &Info = MetadataStore[this];
14167975b8c3SSerge Pavlov assert(!Info.empty() && "bit out of sync with hash table");
14177975b8c3SSerge Pavlov Info.remove_if([&KnownSet](const MDAttachments::Attachment &I) {
14187975b8c3SSerge Pavlov return !KnownSet.count(I.MDKind);
1419cbc28dc5SDuncan P. N. Exon Smith });
1420ab73c493SRafael Espindola
142175ef0c09SDuncan P. N. Exon Smith if (Info.empty()) {
1422ab73c493SRafael Espindola // Drop our entry at the store.
14237975b8c3SSerge Pavlov clearMetadata();
1424ab73c493SRafael Espindola }
1425ab73c493SRafael Espindola }
1426ab73c493SRafael Espindola
setMetadata(unsigned KindID,MDNode * Node)1427de36e804SDuncan P. N. Exon Smith void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
1428de36e804SDuncan P. N. Exon Smith if (!Node && !hasMetadata())
1429de36e804SDuncan P. N. Exon Smith return;
1430ef860a24SChandler Carruth
1431ef860a24SChandler Carruth // Handle 'dbg' as a special case since it is not stored in the hash table.
1432ef860a24SChandler Carruth if (KindID == LLVMContext::MD_dbg) {
1433ab659fb3SDuncan P. N. Exon Smith DbgLoc = DebugLoc(Node);
1434ef860a24SChandler Carruth return;
1435ef860a24SChandler Carruth }
1436ef860a24SChandler Carruth
14377975b8c3SSerge Pavlov Value::setMetadata(KindID, Node);
1438ef860a24SChandler Carruth }
1439ef860a24SChandler Carruth
addAnnotationMetadata(StringRef Name)1440ca2e7e59SFlorian Hahn void Instruction::addAnnotationMetadata(StringRef Name) {
1441ca2e7e59SFlorian Hahn MDBuilder MDB(getContext());
1442ca2e7e59SFlorian Hahn
1443ca2e7e59SFlorian Hahn auto *Existing = getMetadata(LLVMContext::MD_annotation);
1444ca2e7e59SFlorian Hahn SmallVector<Metadata *, 4> Names;
1445ca2e7e59SFlorian Hahn bool AppendName = true;
1446ca2e7e59SFlorian Hahn if (Existing) {
1447ca2e7e59SFlorian Hahn auto *Tuple = cast<MDTuple>(Existing);
1448ca2e7e59SFlorian Hahn for (auto &N : Tuple->operands()) {
1449ca2e7e59SFlorian Hahn if (cast<MDString>(N.get())->getString() == Name)
1450ca2e7e59SFlorian Hahn AppendName = false;
1451ca2e7e59SFlorian Hahn Names.push_back(N.get());
1452ca2e7e59SFlorian Hahn }
1453ca2e7e59SFlorian Hahn }
1454ca2e7e59SFlorian Hahn if (AppendName)
1455ca2e7e59SFlorian Hahn Names.push_back(MDB.createString(Name));
1456ca2e7e59SFlorian Hahn
1457ca2e7e59SFlorian Hahn MDNode *MD = MDTuple::get(getContext(), Names);
1458ca2e7e59SFlorian Hahn setMetadata(LLVMContext::MD_annotation, MD);
1459ca2e7e59SFlorian Hahn }
1460ca2e7e59SFlorian Hahn
getAAMetadata() const14612d1ffad0SMichael Liao AAMDNodes Instruction::getAAMetadata() const {
14622d1ffad0SMichael Liao AAMDNodes Result;
14632d1ffad0SMichael Liao Result.TBAA = getMetadata(LLVMContext::MD_tbaa);
14642d1ffad0SMichael Liao Result.TBAAStruct = getMetadata(LLVMContext::MD_tbaa_struct);
14652d1ffad0SMichael Liao Result.Scope = getMetadata(LLVMContext::MD_alias_scope);
14662d1ffad0SMichael Liao Result.NoAlias = getMetadata(LLVMContext::MD_noalias);
14672d1ffad0SMichael Liao return Result;
14682d1ffad0SMichael Liao }
14692d1ffad0SMichael Liao
setAAMetadata(const AAMDNodes & N)1470cc39b675SHal Finkel void Instruction::setAAMetadata(const AAMDNodes &N) {
1471cc39b675SHal Finkel setMetadata(LLVMContext::MD_tbaa, N.TBAA);
1472a7929533SAnton Afanasyev setMetadata(LLVMContext::MD_tbaa_struct, N.TBAAStruct);
14739414665aSHal Finkel setMetadata(LLVMContext::MD_alias_scope, N.Scope);
14749414665aSHal Finkel setMetadata(LLVMContext::MD_noalias, N.NoAlias);
1475cc39b675SHal Finkel }
1476cc39b675SHal Finkel
getMetadataImpl(unsigned KindID) const1477de36e804SDuncan P. N. Exon Smith MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
1478ef860a24SChandler Carruth // Handle 'dbg' as a special case since it is not stored in the hash table.
1479ef860a24SChandler Carruth if (KindID == LLVMContext::MD_dbg)
14805bf8fef5SDuncan P. N. Exon Smith return DbgLoc.getAsMDNode();
14817975b8c3SSerge Pavlov return Value::getMetadata(KindID);
1482ef860a24SChandler Carruth }
1483ef860a24SChandler Carruth
getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,MDNode * >> & Result) const14844abd1a08SDuncan P. N. Exon Smith void Instruction::getAllMetadataImpl(
1485de36e804SDuncan P. N. Exon Smith SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const {
1486ef860a24SChandler Carruth Result.clear();
1487ef860a24SChandler Carruth
1488ef860a24SChandler Carruth // Handle 'dbg' as a special case since it is not stored in the hash table.
1489ab659fb3SDuncan P. N. Exon Smith if (DbgLoc) {
14905bf8fef5SDuncan P. N. Exon Smith Result.push_back(
14915bf8fef5SDuncan P. N. Exon Smith std::make_pair((unsigned)LLVMContext::MD_dbg, DbgLoc.getAsMDNode()));
1492ef860a24SChandler Carruth }
14937975b8c3SSerge Pavlov Value::getAllMetadata(Result);
1494ef860a24SChandler Carruth }
1495ef860a24SChandler Carruth
extractProfMetadata(uint64_t & TrueVal,uint64_t & FalseVal) const1496e0e0ed13SDehao Chen bool Instruction::extractProfMetadata(uint64_t &TrueVal,
1497e0e0ed13SDehao Chen uint64_t &FalseVal) const {
1498e0e0ed13SDehao Chen assert(
1499e0e0ed13SDehao Chen (getOpcode() == Instruction::Br || getOpcode() == Instruction::Select) &&
1500d66607bdSSanjay Patel "Looking for branch weights on something besides branch or select");
1501d66607bdSSanjay Patel
1502d66607bdSSanjay Patel auto *ProfileData = getMetadata(LLVMContext::MD_prof);
1503d66607bdSSanjay Patel if (!ProfileData || ProfileData->getNumOperands() != 3)
1504d66607bdSSanjay Patel return false;
1505d66607bdSSanjay Patel
1506d66607bdSSanjay Patel auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
1507d66607bdSSanjay Patel if (!ProfDataName || !ProfDataName->getString().equals("branch_weights"))
1508d66607bdSSanjay Patel return false;
1509d66607bdSSanjay Patel
1510d66607bdSSanjay Patel auto *CITrue = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(1));
1511d66607bdSSanjay Patel auto *CIFalse = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(2));
1512d66607bdSSanjay Patel if (!CITrue || !CIFalse)
1513d66607bdSSanjay Patel return false;
1514d66607bdSSanjay Patel
1515d66607bdSSanjay Patel TrueVal = CITrue->getValue().getZExtValue();
1516d66607bdSSanjay Patel FalseVal = CIFalse->getValue().getZExtValue();
1517d66607bdSSanjay Patel
1518d66607bdSSanjay Patel return true;
1519d66607bdSSanjay Patel }
1520d66607bdSSanjay Patel
extractProfTotalWeight(uint64_t & TotalVal) const1521e0e0ed13SDehao Chen bool Instruction::extractProfTotalWeight(uint64_t &TotalVal) const {
152222998738Sspupyrev assert(
152322998738Sspupyrev (getOpcode() == Instruction::Br || getOpcode() == Instruction::Select ||
152422998738Sspupyrev getOpcode() == Instruction::Call || getOpcode() == Instruction::Invoke ||
152522998738Sspupyrev getOpcode() == Instruction::IndirectBr ||
1526e9d07523SDehao Chen getOpcode() == Instruction::Switch) &&
15279232f982SDehao Chen "Looking for branch weights on something besides branch");
15289232f982SDehao Chen
15299232f982SDehao Chen TotalVal = 0;
15309232f982SDehao Chen auto *ProfileData = getMetadata(LLVMContext::MD_prof);
15319232f982SDehao Chen if (!ProfileData)
15329232f982SDehao Chen return false;
15339232f982SDehao Chen
15349232f982SDehao Chen auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0));
1535fed890eaSDehao Chen if (!ProfDataName)
15369232f982SDehao Chen return false;
15379232f982SDehao Chen
1538fed890eaSDehao Chen if (ProfDataName->getString().equals("branch_weights")) {
15399232f982SDehao Chen TotalVal = 0;
1540dd8f6bddSDavid Majnemer for (unsigned i = 1; i < ProfileData->getNumOperands(); i++) {
15419232f982SDehao Chen auto *V = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(i));
15429232f982SDehao Chen if (!V)
15439232f982SDehao Chen return false;
15449232f982SDehao Chen TotalVal += V->getValue().getZExtValue();
15459232f982SDehao Chen }
15469232f982SDehao Chen return true;
1547fed890eaSDehao Chen } else if (ProfDataName->getString().equals("VP") &&
1548fed890eaSDehao Chen ProfileData->getNumOperands() > 3) {
1549fed890eaSDehao Chen TotalVal = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(2))
1550fed890eaSDehao Chen ->getValue()
1551fed890eaSDehao Chen .getZExtValue();
1552fed890eaSDehao Chen return true;
1553fed890eaSDehao Chen }
1554fed890eaSDehao Chen return false;
15559232f982SDehao Chen }
15569232f982SDehao Chen
copyMetadata(const GlobalObject * Other,unsigned Offset)15577efd7506SPeter Collingbourne void GlobalObject::copyMetadata(const GlobalObject *Other, unsigned Offset) {
15584f7c16ddSPeter Collingbourne SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
15594f7c16ddSPeter Collingbourne Other->getAllMetadata(MDs);
15607efd7506SPeter Collingbourne for (auto &MD : MDs) {
15617efd7506SPeter Collingbourne // We need to adjust the type metadata offset.
15627efd7506SPeter Collingbourne if (Offset != 0 && MD.first == LLVMContext::MD_type) {
15637efd7506SPeter Collingbourne auto *OffsetConst = cast<ConstantInt>(
15647efd7506SPeter Collingbourne cast<ConstantAsMetadata>(MD.second->getOperand(0))->getValue());
15657efd7506SPeter Collingbourne Metadata *TypeId = MD.second->getOperand(1);
15667efd7506SPeter Collingbourne auto *NewOffsetMD = ConstantAsMetadata::get(ConstantInt::get(
15677efd7506SPeter Collingbourne OffsetConst->getType(), OffsetConst->getValue() + Offset));
15687efd7506SPeter Collingbourne addMetadata(LLVMContext::MD_type,
15697efd7506SPeter Collingbourne *MDNode::get(getContext(), {NewOffsetMD, TypeId}));
15707efd7506SPeter Collingbourne continue;
15717efd7506SPeter Collingbourne }
1572d4135bbcSPeter Collingbourne // If an offset adjustment was specified we need to modify the DIExpression
1573d4135bbcSPeter Collingbourne // to prepend the adjustment:
1574d4135bbcSPeter Collingbourne // !DIExpression(DW_OP_plus, Offset, [original expr])
1575bceaaa96SAdrian Prantl auto *Attachment = MD.second;
1576d4135bbcSPeter Collingbourne if (Offset != 0 && MD.first == LLVMContext::MD_dbg) {
1577bceaaa96SAdrian Prantl DIGlobalVariable *GV = dyn_cast<DIGlobalVariable>(Attachment);
1578bceaaa96SAdrian Prantl DIExpression *E = nullptr;
1579bceaaa96SAdrian Prantl if (!GV) {
1580bceaaa96SAdrian Prantl auto *GVE = cast<DIGlobalVariableExpression>(Attachment);
1581bceaaa96SAdrian Prantl GV = GVE->getVariable();
1582bceaaa96SAdrian Prantl E = GVE->getExpression();
1583bceaaa96SAdrian Prantl }
1584d4135bbcSPeter Collingbourne ArrayRef<uint64_t> OrigElements;
1585d4135bbcSPeter Collingbourne if (E)
1586d4135bbcSPeter Collingbourne OrigElements = E->getElements();
1587d4135bbcSPeter Collingbourne std::vector<uint64_t> Elements(OrigElements.size() + 2);
1588ffc498dfSFlorian Hahn Elements[0] = dwarf::DW_OP_plus_uconst;
1589d4135bbcSPeter Collingbourne Elements[1] = Offset;
159075709329SFangrui Song llvm::copy(OrigElements, Elements.begin() + 2);
1591bceaaa96SAdrian Prantl E = DIExpression::get(getContext(), Elements);
1592bceaaa96SAdrian Prantl Attachment = DIGlobalVariableExpression::get(getContext(), GV, E);
1593d4135bbcSPeter Collingbourne }
1594bceaaa96SAdrian Prantl addMetadata(MD.first, *Attachment);
15954f7c16ddSPeter Collingbourne }
15967efd7506SPeter Collingbourne }
15977efd7506SPeter Collingbourne
addTypeMetadata(unsigned Offset,Metadata * TypeID)15987efd7506SPeter Collingbourne void GlobalObject::addTypeMetadata(unsigned Offset, Metadata *TypeID) {
15997efd7506SPeter Collingbourne addMetadata(
16007efd7506SPeter Collingbourne LLVMContext::MD_type,
16017efd7506SPeter Collingbourne *MDTuple::get(getContext(),
1602de6cce22SEugene Zelenko {ConstantAsMetadata::get(ConstantInt::get(
16037efd7506SPeter Collingbourne Type::getInt64Ty(getContext()), Offset)),
16047efd7506SPeter Collingbourne TypeID}));
16057efd7506SPeter Collingbourne }
16064f7c16ddSPeter Collingbourne
setVCallVisibilityMetadata(VCallVisibility Visibility)1607458676dbSTeresa Johnson void GlobalObject::setVCallVisibilityMetadata(VCallVisibility Visibility) {
1608458676dbSTeresa Johnson // Remove any existing vcall visibility metadata first in case we are
1609458676dbSTeresa Johnson // updating.
1610458676dbSTeresa Johnson eraseMetadata(LLVMContext::MD_vcall_visibility);
16113b598b9cSOliver Stannard addMetadata(LLVMContext::MD_vcall_visibility,
16123b598b9cSOliver Stannard *MDNode::get(getContext(),
16133b598b9cSOliver Stannard {ConstantAsMetadata::get(ConstantInt::get(
16143b598b9cSOliver Stannard Type::getInt64Ty(getContext()), Visibility))}));
16153b598b9cSOliver Stannard }
16163b598b9cSOliver Stannard
getVCallVisibility() const16173b598b9cSOliver Stannard GlobalObject::VCallVisibility GlobalObject::getVCallVisibility() const {
16183b598b9cSOliver Stannard if (MDNode *MD = getMetadata(LLVMContext::MD_vcall_visibility)) {
16193b598b9cSOliver Stannard uint64_t Val = cast<ConstantInt>(
16203b598b9cSOliver Stannard cast<ConstantAsMetadata>(MD->getOperand(0))->getValue())
16213b598b9cSOliver Stannard ->getZExtValue();
16223b598b9cSOliver Stannard assert(Val <= 2 && "unknown vcall visibility!");
16233b598b9cSOliver Stannard return (VCallVisibility)Val;
16243b598b9cSOliver Stannard }
16253b598b9cSOliver Stannard return VCallVisibility::VCallVisibilityPublic;
16263b598b9cSOliver Stannard }
16273b598b9cSOliver Stannard
setSubprogram(DISubprogram * SP)1628b56b5af4SDuncan P. N. Exon Smith void Function::setSubprogram(DISubprogram *SP) {
1629b56b5af4SDuncan P. N. Exon Smith setMetadata(LLVMContext::MD_dbg, SP);
1630b56b5af4SDuncan P. N. Exon Smith }
1631b56b5af4SDuncan P. N. Exon Smith
getSubprogram() const1632b56b5af4SDuncan P. N. Exon Smith DISubprogram *Function::getSubprogram() const {
1633b56b5af4SDuncan P. N. Exon Smith return cast_or_null<DISubprogram>(getMetadata(LLVMContext::MD_dbg));
1634b56b5af4SDuncan P. N. Exon Smith }
1635d4135bbcSPeter Collingbourne
isDebugInfoForProfiling() const1636fb02f714SDehao Chen bool Function::isDebugInfoForProfiling() const {
1637fb02f714SDehao Chen if (DISubprogram *SP = getSubprogram()) {
1638fb02f714SDehao Chen if (DICompileUnit *CU = SP->getUnit()) {
1639fb02f714SDehao Chen return CU->getDebugInfoForProfiling();
1640fb02f714SDehao Chen }
1641fb02f714SDehao Chen }
1642fb02f714SDehao Chen return false;
1643fb02f714SDehao Chen }
1644fb02f714SDehao Chen
addDebugInfo(DIGlobalVariableExpression * GV)1645bceaaa96SAdrian Prantl void GlobalVariable::addDebugInfo(DIGlobalVariableExpression *GV) {
1646d4135bbcSPeter Collingbourne addMetadata(LLVMContext::MD_dbg, *GV);
1647d4135bbcSPeter Collingbourne }
1648d4135bbcSPeter Collingbourne
getDebugInfo(SmallVectorImpl<DIGlobalVariableExpression * > & GVs) const1649d4135bbcSPeter Collingbourne void GlobalVariable::getDebugInfo(
1650bceaaa96SAdrian Prantl SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const {
1651d4135bbcSPeter Collingbourne SmallVector<MDNode *, 1> MDs;
1652d4135bbcSPeter Collingbourne getMetadata(LLVMContext::MD_dbg, MDs);
1653d4135bbcSPeter Collingbourne for (MDNode *MD : MDs)
1654bceaaa96SAdrian Prantl GVs.push_back(cast<DIGlobalVariableExpression>(MD));
1655d4135bbcSPeter Collingbourne }
1656