summaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen/MachineConstantPool.h
blob: 6bb2665985ece2be7035cc241eb916932c530baf (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
//===-- CodeGen/MachineConstantPool.h - Abstract Constant Pool --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// @file This file declares the MachineConstantPool class which is an abstract
/// constant pool to keep track of constants referenced by a function.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_MACHINECONSTANTPOOL_H
#define LLVM_CODEGEN_MACHINECONSTANTPOOL_H

#include "llvm/ADT/FoldingSet.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Support/Streams.h"
#include <vector>
#include <iosfwd>

namespace llvm {

class AsmPrinter;
class Constant;
class TargetData;
class TargetMachine;
class MachineConstantPool;

/// Abstract base class for all machine specific constantpool value subclasses.
///
class MachineConstantPoolValue {
  const Type *Ty;

public:
  MachineConstantPoolValue(const Type *ty) : Ty(ty) {}
  virtual ~MachineConstantPoolValue() {};

  /// getType - get type of this MachineConstantPoolValue.
  ///
  inline const Type *getType() const { return Ty; }

  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
                                        unsigned Alignment) = 0;

  virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID) = 0;

  /// print - Implement operator<<...
  ///
  void print(llvm_ostream &O) const {
    if (O.stream()) print(*O.stream());
  }
  virtual void print(std::ostream &O) const = 0;
};

inline llvm_ostream &operator<<(llvm_ostream &OS,
                                const MachineConstantPoolValue &V) {
  V.print(OS);
  return OS;
}
inline std::ostream &operator<<(std::ostream &OS,
                                const MachineConstantPoolValue &V) {
  V.print(OS);
  return OS;
}

/// This class is a data container for one entry in a MachineConstantPool.
/// It contains a pointer to the value and an offset from the start of
/// the constant pool.
/// @brief An entry in a MachineConstantPool
class MachineConstantPoolEntry {
public:
  /// The constant itself.
  union {
    Constant *ConstVal;
    MachineConstantPoolValue *MachineCPVal;
  } Val;

  /// The offset of the constant from the start of the pool. The top bit is set
  /// when Val is a MachineConstantPoolValue.
  unsigned Offset;

  MachineConstantPoolEntry(Constant *V, unsigned O)
    : Offset(O) {
    assert((int)Offset >= 0 && "Offset is too large");
    Val.ConstVal = V;
  }
  MachineConstantPoolEntry(MachineConstantPoolValue *V, unsigned O)
    : Offset(O){
    assert((int)Offset >= 0 && "Offset is too large");
    Val.MachineCPVal = V; 
    Offset |= 1 << (sizeof(unsigned)*8-1);
  }

  bool isMachineConstantPoolEntry() const {
    return (int)Offset < 0;
  }

  int getOffset() const { 
    return Offset & ~(1 << (sizeof(unsigned)*8-1));
  }

  const Type *getType() const;
};
  
/// The MachineConstantPool class keeps track of constants referenced by a
/// function which must be spilled to memory.  This is used for constants which
/// are unable to be used directly as operands to instructions, which typically
/// include floating point and large integer constants.
///
/// Instructions reference the address of these constant pool constants through
/// the use of MO_ConstantPoolIndex values.  When emitting assembly or machine
/// code, these virtual address references are converted to refer to the
/// address of the function constant pool values.
/// @brief The machine constant pool.
class MachineConstantPool {
  const TargetData *TD;   ///< The machine's TargetData.
  unsigned PoolAlignment; ///< The alignment for the pool.
  std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
public:
  /// @brief The only constructor.
  MachineConstantPool(const TargetData *td) : TD(td), PoolAlignment(1) {}
  ~MachineConstantPool();
    
  /// getConstantPoolAlignment - Return the log2 of the alignment required by
  /// the whole constant pool, of which the first element must be aligned.
  unsigned getConstantPoolAlignment() const { return PoolAlignment; }
  
  /// getConstantPoolIndex - Create a new entry in the constant pool or return
  /// an existing one.  User must specify an alignment in bytes for the object.
  unsigned getConstantPoolIndex(Constant *C, unsigned Alignment);
  unsigned getConstantPoolIndex(MachineConstantPoolValue *V,unsigned Alignment);
  
  /// isEmpty - Return true if this constant pool contains no constants.
  bool isEmpty() const { return Constants.empty(); }

  const std::vector<MachineConstantPoolEntry> &getConstants() const {
    return Constants;
  }

  /// print - Used by the MachineFunction printer to print information about
  /// constant pool objects.  Implemented in MachineFunction.cpp
  ///
  void print(llvm_ostream &OS) const {
    if (OS.stream()) print(*OS.stream());
  }
  void print(std::ostream &OS) const;

  /// dump - Call print(std::cerr) to be called from the debugger.
  ///
  void dump() const;
};

} // End llvm namespace

#endif