aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h
blob: 469022f34c56472cd6f50f32076c9f85e873c25e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//===- ValueMapper.h - Remapping for constants and metadata -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MapValue interface which is used by various parts of
// the Transforms/Utils library to implement cloning and linking facilities.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
#define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H

#include "llvm/IR/ValueMap.h"

namespace llvm {
  class Value;
  class Instruction;
  typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy;

  /// ValueMapTypeRemapper - This is a class that can be implemented by clients
  /// to remap types when cloning constants and instructions.
  class ValueMapTypeRemapper {
    virtual void anchor();  // Out of line method.
  public:
    virtual ~ValueMapTypeRemapper() {}

    /// remapType - The client should implement this method if they want to
    /// remap types while mapping values.
    virtual Type *remapType(Type *SrcTy) = 0;
  };

  /// ValueMaterializer - This is a class that can be implemented by clients
  /// to materialize Values on demand.
  class ValueMaterializer {
    virtual void anchor(); // Out of line method.

  protected:
    ~ValueMaterializer() = default;
    ValueMaterializer() = default;
    ValueMaterializer(const ValueMaterializer&) = default;
    ValueMaterializer &operator=(const ValueMaterializer&) = default;

  public:
    /// The client should implement this method if they want to generate a
    /// mapped Value on demand. For example, if linking lazily.
    virtual Value *materializeDeclFor(Value *V) = 0;

    /// If the data being mapped is recursive, the above function can map
    /// just the declaration and this is called to compute the initializer.
    /// It is called after the mapping is recorded, so it doesn't need to worry
    /// about recursion.
    virtual void materializeInitFor(GlobalValue *New, GlobalValue *Old);

    /// If the client needs to handle temporary metadata it must implement
    /// these methods.
    virtual Metadata *mapTemporaryMetadata(Metadata *MD) { return nullptr; }
    virtual void replaceTemporaryMetadata(const Metadata *OrigMD,
                                          Metadata *NewMD) {}

    /// The client should implement this method if some metadata need
    /// not be mapped, for example DISubprogram metadata for functions not
    /// linked into the destination module.
    virtual bool isMetadataNeeded(Metadata *MD) { return true; }
  };

  /// RemapFlags - These are flags that the value mapping APIs allow.
  enum RemapFlags {
    RF_None = 0,

    /// RF_NoModuleLevelChanges - If this flag is set, the remapper knows that
    /// only local values within a function (such as an instruction or argument)
    /// are mapped, not global values like functions and global metadata.
    RF_NoModuleLevelChanges = 1,

    /// RF_IgnoreMissingEntries - If this flag is set, the remapper ignores
    /// entries that are not in the value map.  If it is unset, it aborts if an
    /// operand is asked to be remapped which doesn't exist in the mapping.
    RF_IgnoreMissingEntries = 2,

    /// Instruct the remapper to move distinct metadata instead of duplicating
    /// it when there are module-level changes.
    RF_MoveDistinctMDs = 4,

    /// Any global values not in value map are mapped to null instead of
    /// mapping to self. Illegal if RF_IgnoreMissingEntries is also set.
    RF_NullMapMissingGlobalValues = 8,

    /// Set when there is still temporary metadata that must be handled,
    /// such as when we are doing function importing and will materialize
    /// and link metadata as a postpass.
    RF_HaveUnmaterializedMetadata = 16,
  };

  static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
    return RemapFlags(unsigned(LHS)|unsigned(RHS));
  }

  Value *MapValue(const Value *V, ValueToValueMapTy &VM,
                  RemapFlags Flags = RF_None,
                  ValueMapTypeRemapper *TypeMapper = nullptr,
                  ValueMaterializer *Materializer = nullptr);

  Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
                        RemapFlags Flags = RF_None,
                        ValueMapTypeRemapper *TypeMapper = nullptr,
                        ValueMaterializer *Materializer = nullptr);

  /// MapMetadata - provide versions that preserve type safety for MDNodes.
  MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
                      RemapFlags Flags = RF_None,
                      ValueMapTypeRemapper *TypeMapper = nullptr,
                      ValueMaterializer *Materializer = nullptr);

  void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
                        RemapFlags Flags = RF_None,
                        ValueMapTypeRemapper *TypeMapper = nullptr,
                        ValueMaterializer *Materializer = nullptr);

  /// MapValue - provide versions that preserve type safety for Constants.
  inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
                            RemapFlags Flags = RF_None,
                            ValueMapTypeRemapper *TypeMapper = nullptr,
                            ValueMaterializer *Materializer = nullptr) {
    return cast<Constant>(MapValue((const Value*)V, VM, Flags, TypeMapper,
                                   Materializer));
  }

} // End llvm namespace

#endif