summaryrefslogtreecommitdiff
path: root/include/llvm/iMemory.h
blob: f57a019af42e4ee6c087585270779a130a95e9e7 (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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
//===-- llvm/iMemory.h - Memory Operator node definitions --------*- C++ -*--=//
//
// This file contains the declarations of all of the memory related operators.
// This includes: malloc, free, alloca, load, store, getfield, putfield
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_IMEMORY_H
#define LLVM_IMEMORY_H

#include "llvm/Instruction.h"
#include "llvm/DerivedTypes.h"

//===----------------------------------------------------------------------===//
//                             AllocationInst Class
//===----------------------------------------------------------------------===//
//
// AllocationInst - This class is the common base class of MallocInst and
// AllocaInst.
//
class AllocationInst : public Instruction {
public:
  AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
		 const string &Name = "")
    : Instruction(Ty, iTy, Name) {
    assert(Ty->isPointerType() && "Can't allocate a non pointer type!");

    if (ArraySize) {
      // Make sure they didn't try to specify a size for !(unsized array) type
      assert((getType()->getValueType()->isArrayType() && 
	      ((const ArrayType*)getType()->getValueType())->isUnsized()) && 
          "Trying to allocate something other than unsized array, with size!");

      Operands.reserve(1);
      Operands.push_back(Use(ArraySize, this));
    }
  }

  // getType - Overload to return most specific pointer type...
  inline const PointerType *getType() const {
    return (const PointerType*)Instruction::getType(); 
  }

  virtual Instruction *clone() const = 0;
};


//===----------------------------------------------------------------------===//
//                                MallocInst Class
//===----------------------------------------------------------------------===//

class MallocInst : public AllocationInst {
public:
  MallocInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") 
    : AllocationInst(Ty, ArraySize, Malloc, Name) {}

  virtual Instruction *clone() const { 
    return new MallocInst(getType(), Operands.size() ? Operands[1] : 0);
  }

  virtual const char *getOpcodeName() const { return "malloc"; }
};


//===----------------------------------------------------------------------===//
//                                AllocaInst Class
//===----------------------------------------------------------------------===//

class AllocaInst : public AllocationInst {
public:
  AllocaInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") 
    : AllocationInst(Ty, ArraySize, Alloca, Name) {}

  virtual Instruction *clone() const { 
    return new AllocaInst(getType(), Operands.size() ? Operands[1] : 0);
  }

  virtual const char *getOpcodeName() const { return "alloca"; }
};


//===----------------------------------------------------------------------===//
//                                 FreeInst Class
//===----------------------------------------------------------------------===//

class FreeInst : public Instruction {
public:
  FreeInst(Value *Ptr, const string &Name = "") 
    : Instruction(Type::VoidTy, Free, Name) {
    assert(Ptr->getType()->isPointerType() && "Can't free nonpointer!");
    Operands.reserve(1);
    Operands.push_back(Use(Ptr, this));
  }

  virtual Instruction *clone() const { return new FreeInst(Operands[0]); }

  virtual const char *getOpcodeName() const { return "free"; }

  virtual bool hasSideEffects() const { return true; }
};


//===----------------------------------------------------------------------===//
//                              MemAccessInst Class
//===----------------------------------------------------------------------===//
//
// MemAccessInst - Common base class of LoadInst, StoreInst, and
// GetElementPtrInst...
//
class MemAccessInst : public Instruction {
protected:
  inline MemAccessInst(const Type *Ty, unsigned Opcode,
		       const vector<ConstPoolVal*> &Idx,
		       const string &Nam = "")
    : Instruction(Ty, Opcode, Nam),
      indexVec(Idx)
  {}
  
protected:
  vector<ConstPoolVal*> indexVec;
  
public:
  // getIndexedType - Returns the type of the element that would be loaded with
  // a load instruction with the specified parameters.
  //
  // A null type is returned if the indices are invalid for the specified 
  // pointer type.
  //
  static const Type *getIndexedType(const Type *Ptr, 
				    const vector<ConstPoolVal*> &Indices,
				    bool AllowStructLeaf = false);
  
  static unsigned int getIndexedOfsetForTarget(const Type *Ptr, 
					  const vector<ConstPoolVal*> &Indices,
					  const TargetMachine& targetMachine);
  
  const vector<ConstPoolVal*>& getIndexVec() const { return indexVec; }
  
  virtual Value* getPtrOperand() = 0;
  
  virtual int	getFirstOffsetIdx() const = 0;
};


//===----------------------------------------------------------------------===//
//                                LoadInst Class
//===----------------------------------------------------------------------===//

class LoadInst : public MemAccessInst {
  LoadInst(const LoadInst &LI) : MemAccessInst(LI.getType(), Load, LI.getIndexVec()) {
    Operands.reserve(LI.Operands.size());
    for (unsigned i = 0, E = LI.Operands.size(); i != E; ++i)
      Operands.push_back(Use(LI.Operands[i], this));
  }
public:
  LoadInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
	   const string &Name = "");
  virtual Instruction*	clone() const { return new LoadInst(*this); }
  virtual const char*	getOpcodeName() const { return "load"; }  
  virtual Value*	getPtrOperand() { return this->getOperand(0); }
  virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 1)? 1 : -1;}
};


//===----------------------------------------------------------------------===//
//                                StoreInst Class
//===----------------------------------------------------------------------===//

class StoreInst : public MemAccessInst {
  StoreInst(const StoreInst &SI) : MemAccessInst(SI.getType(), Store, SI.getIndexVec()) {
    Operands.reserve(SI.Operands.size());
    for (unsigned i = 0, E = SI.Operands.size(); i != E; ++i)
      Operands.push_back(Use(SI.Operands[i], this));
  }
public:
  StoreInst(Value *Val, Value *Ptr, const vector<ConstPoolVal*> &Idx,
	    const string &Name = "");
  virtual Instruction *clone() const { return new StoreInst(*this); }
  virtual const char *getOpcodeName() const { return "store"; }  
  
  virtual bool hasSideEffects() const { return true; }
  virtual Value*	getPtrOperand()	{ return this->getOperand(1); }
  virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 2)? 2 : -1;}
};


//===----------------------------------------------------------------------===//
//                             GetElementPtrInst Class
//===----------------------------------------------------------------------===//

class GetElementPtrInst : public MemAccessInst {
  GetElementPtrInst(const GetElementPtrInst &EPI)
    : MemAccessInst(EPI.getType(), GetElementPtr, EPI.getIndexVec()) {
    Operands.reserve(EPI.Operands.size());
    for (unsigned i = 0, E = EPI.Operands.size(); i != E; ++i)
      Operands.push_back(Use(EPI.Operands[i], this));
  }
public:
  GetElementPtrInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
		    const string &Name = "");
  virtual Instruction *clone() const { return new GetElementPtrInst(*this); }
  virtual const char *getOpcodeName() const { return "getelementptr"; }  
  virtual Value*	getPtrOperand()	{ return this->getOperand(0); }
  virtual int getFirstOffsetIdx() const { return (this->getNumOperands() > 1)? 1 : -1;}
  
  inline bool isArraySelector() const { return !isStructSelector(); }
  bool isStructSelector() const;
};

#endif // LLVM_IMEMORY_H