1 //===-- llvm/IR/ModuleSlotTracker.h -----------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_IR_MODULESLOTTRACKER_H 10 #define LLVM_IR_MODULESLOTTRACKER_H 11 12 #include <functional> 13 #include <memory> 14 #include <utility> 15 #include <vector> 16 17 namespace llvm { 18 19 class Module; 20 class Function; 21 class SlotTracker; 22 class Value; 23 class MDNode; 24 25 /// Abstract interface of slot tracker storage. 26 class AbstractSlotTrackerStorage { 27 public: 28 virtual ~AbstractSlotTrackerStorage(); 29 30 virtual unsigned getNextMetadataSlot() = 0; 31 32 virtual void createMetadataSlot(const MDNode *) = 0; 33 virtual int getMetadataSlot(const MDNode *) = 0; 34 }; 35 36 /// Manage lifetime of a slot tracker for printing IR. 37 /// 38 /// Wrapper around the \a SlotTracker used internally by \a AsmWriter. This 39 /// class allows callers to share the cost of incorporating the metadata in a 40 /// module or a function. 41 /// 42 /// If the IR changes from underneath \a ModuleSlotTracker, strings like 43 /// "<badref>" will be printed, or, worse, the wrong slots entirely. 44 class ModuleSlotTracker { 45 /// Storage for a slot tracker. 46 std::unique_ptr<SlotTracker> MachineStorage; 47 bool ShouldCreateStorage = false; 48 bool ShouldInitializeAllMetadata = false; 49 50 const Module *M = nullptr; 51 const Function *F = nullptr; 52 SlotTracker *Machine = nullptr; 53 54 std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)> 55 ProcessModuleHookFn; 56 std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)> 57 ProcessFunctionHookFn; 58 59 public: 60 /// Wrap a preinitialized SlotTracker. 61 ModuleSlotTracker(SlotTracker &Machine, const Module *M, 62 const Function *F = nullptr); 63 64 /// Construct a slot tracker from a module. 65 /// 66 /// If \a M is \c nullptr, uses a null slot tracker. Otherwise, initializes 67 /// a slot tracker, and initializes all metadata slots. \c 68 /// ShouldInitializeAllMetadata defaults to true because this is expected to 69 /// be shared between multiple callers, and otherwise MDNode references will 70 /// not match up. 71 explicit ModuleSlotTracker(const Module *M, 72 bool ShouldInitializeAllMetadata = true); 73 74 /// Destructor to clean up storage. 75 virtual ~ModuleSlotTracker(); 76 77 /// Lazily creates a slot tracker. 78 SlotTracker *getMachine(); 79 getModule()80 const Module *getModule() const { return M; } getCurrentFunction()81 const Function *getCurrentFunction() const { return F; } 82 83 /// Incorporate the given function. 84 /// 85 /// Purge the currently incorporated function and incorporate \c F. If \c F 86 /// is currently incorporated, this is a no-op. 87 void incorporateFunction(const Function &F); 88 89 /// Return the slot number of the specified local value. 90 /// 91 /// A function that defines this value should be incorporated prior to calling 92 /// this method. 93 /// Return -1 if the value is not in the function's SlotTracker. 94 int getLocalSlot(const Value *V); 95 96 void setProcessHook( 97 std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>); 98 void setProcessHook(std::function<void(AbstractSlotTrackerStorage *, 99 const Function *, bool)>); 100 101 using MachineMDNodeListType = 102 std::vector<std::pair<unsigned, const MDNode *>>; 103 104 void collectMDNodes(MachineMDNodeListType &L, unsigned LB, unsigned UB) const; 105 }; 106 107 } // end namespace llvm 108 109 #endif 110