aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.h
blob: cc43c7a1e234621d6687a7e2f8459f4451afe6bb (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//===-- Bitcode/NaCl/Writer/NaClValueEnumerator.h - ----------*- C++ -*-===//
//      Number values.
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class gives values and types Unique ID's.
//
//===----------------------------------------------------------------------===//

#ifndef NACL_VALUE_ENUMERATOR_H
#define NACL_VALUE_ENUMERATOR_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
#include <vector>

namespace llvm {

class Type;
class Value;
class Instruction;
class BasicBlock;
class Function;
class Module;
class ValueSymbolTable;
class raw_ostream;

class NaClValueEnumerator {
public:
  typedef std::vector<Type*> TypeList;

  // For each value, we remember its Value* and occurrence frequency.
  typedef std::vector<std::pair<const Value*, unsigned> > ValueList;
private:
  // Defines unique ID's for each type.
  typedef DenseMap<Type*, unsigned> TypeMapType;
  TypeMapType TypeMap;
  // Defines the number of references to each type. If defined,
  // we are in the first pass of collecting types, and reference counts
  // should be added to the map. If undefined, we are in the second pass
  // that actually assigns type IDs, based on frequency counts found in
  // the first pass.
  typedef TypeMapType TypeCountMapType;
  TypeCountMapType* TypeCountMap;

  TypeList Types;

  typedef DenseMap<const Value*, unsigned> ValueMapType;
  ValueMapType ValueMap;
  ValueList Values;

  typedef DenseMap<const Instruction*, unsigned> InstructionMapType;
  InstructionMapType InstructionMap;
  unsigned InstructionCount;

  /// BasicBlocks - This contains all the basic blocks for the currently
  /// incorporated function.  Their reverse mapping is stored in ValueMap.
  std::vector<const BasicBlock*> BasicBlocks;

  /// When a function is incorporated, this is the size of the Values list
  /// before incorporation.
  unsigned NumModuleValues;

  unsigned FirstFuncConstantID;
  unsigned FirstInstID;

  /// Holds values that have been forward referenced within a function.
  /// Used to make sure we don't generate more forward reference declarations
  /// than necessary.
  SmallSet<unsigned, 32> FnForwardTypeRefs;

  // The index of the first global variable ID in the bitcode file.
  unsigned FirstGlobalVarID;
  // The number of global variable IDs defined in the bitcode file.
  unsigned NumGlobalVarIDs;

  // The version of PNaCl bitcode to generate.
  uint32_t PNaClVersion;

  /// \brief Integer type use for PNaCl conversion of pointers.
  Type *IntPtrType;

  NaClValueEnumerator(const NaClValueEnumerator &) LLVM_DELETED_FUNCTION;
  void operator=(const NaClValueEnumerator &) LLVM_DELETED_FUNCTION;
public:
  NaClValueEnumerator(const Module *M, uint32_t PNaClVersion);

  void dump() const;
  void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const;

  unsigned getFirstGlobalVarID() const {
    return FirstGlobalVarID;
  }

  unsigned getNumGlobalVarIDs() const {
    return NumGlobalVarIDs;
  }

  unsigned getValueID(const Value *V) const;

  unsigned getTypeID(Type *T) const {
    TypeMapType::const_iterator I = TypeMap.find(NormalizeType(T));
    assert(I != TypeMap.end() && "Type not in NaClValueEnumerator!");
    return I->second-1;
  }

  unsigned getInstructionID(const Instruction *I) const;
  void setInstructionID(const Instruction *I);

  /// getFunctionConstantRange - Return the range of values that corresponds to
  /// function-local constants.
  void getFunctionConstantRange(unsigned &Start, unsigned &End) const {
    Start = FirstFuncConstantID;
    End = FirstInstID;
  }

  /// \brief Inserts the give value into the set of known function forward
  /// value type refs. Returns true if the value id is added to the set.
  bool InsertFnForwardTypeRef(unsigned ValID) {
    return FnForwardTypeRefs.insert(ValID);
  }

  const ValueList &getValues() const { return Values; }
  const TypeList &getTypes() const { return Types; }
  const std::vector<const BasicBlock*> &getBasicBlocks() const {
    return BasicBlocks;
  }

  /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
  /// use these two methods to get its data into the NaClValueEnumerator!
  ///
  void incorporateFunction(const Function &F);
  void purgeFunction();

  /// \brief Returns the value after elided (cast) operations have been
  /// removed. Returns V if unable to elide the cast.
  const Value *ElideCasts(const Value *V);

  /// \brief Returns true if value V is an elided (cast) operation.
  bool IsElidedCast(const Value *V) {
    return V != ElideCasts(V);
  }

  /// \brief Returns true if the type of V is the integer used to
  /// model pointers in PNaCl.
  bool IsIntPtrType(Type *T) const {
    return T == IntPtrType;
  }

  Type *NormalizeType(Type *Ty) const;

private:
  void OptimizeTypes(const Module *M);
  void OptimizeConstants(unsigned CstStart, unsigned CstEnd);

  void EnumerateValue(const Value *V);
  void EnumerateType(Type *T, bool InsideOptimizeTypes=false);
  void EnumerateOperandType(const Value *V);

  void EnumerateValueSymbolTable(const ValueSymbolTable &ST);
};

} // End llvm namespace

#endif