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