1 //===-- iMemory.cpp - Implement Memory instructions --------------*- C++ -*--=//
3 // This file implements the various memory related classes defined in iMemory.h
5 //===----------------------------------------------------------------------===//
7 #include "llvm/iMemory.h"
9 static inline const Type *checkType(const Type *Ty) {
10 assert(Ty && "Invalid indices for type!");
14 //===----------------------------------------------------------------------===//
15 // MemAccessInst Implementation
16 //===----------------------------------------------------------------------===//
18 // getIndexedType - Returns the type of the element that would be loaded with
19 // a load instruction with the specified parameters.
21 // A null type is returned if the indices are invalid for the specified
24 const Type* MemAccessInst::getIndexedType(const Type *Ptr,
25 const vector<Value*> &Idx,
26 bool AllowCompositeLeaf = false) {
27 if (!Ptr->isPointerType()) return 0; // Type isn't a pointer type!
29 // Handle the special case of the empty set index set...
30 if (Idx.empty()) return cast<PointerType>(Ptr)->getElementType();
33 while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
34 if (Idx.size() == CurIDX) {
35 if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr;
36 return 0; // Can't load a whole structure or array!?!?
39 Value *Index = Idx[CurIDX++];
40 if (!CT->indexValid(Index)) return 0;
41 Ptr = CT->getTypeAtIndex(Index);
43 return CurIDX == Idx.size() ? Ptr : 0;
48 #include "llvm/ConstantVals.h"
49 const vector<Constant*> MemAccessInst::getIndicesBROKEN() const {
50 cerr << "FIXME: MemAccessInst::getIndices() should not be used!\n";
52 vector<Constant*> RetVal;
54 // THIS CODE WILL FAIL IF A NON CONSTANT INDEX IS USED AS AN ARRAY INDEX
55 // THIS IS WHY YOU SHOULD NOT USE THIS FUNCTION ANY MORE!!!
56 for (unsigned i = getFirstIndexOperandNumber(); i < getNumOperands(); ++i)
57 RetVal.push_back(cast<Constant>(getOperand(i)));
63 //===----------------------------------------------------------------------===//
64 // LoadInst Implementation
65 //===----------------------------------------------------------------------===//
67 LoadInst::LoadInst(Value *Ptr, const vector<Value*> &Idx,
68 const string &Name = "")
69 : MemAccessInst(checkType(getIndexedType(Ptr->getType(), Idx)), Load, Name) {
70 assert(getIndexedType(Ptr->getType(), Idx) && "Load operands invalid!");
71 Operands.reserve(1+Idx.size());
72 Operands.push_back(Use(Ptr, this));
74 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
75 Operands.push_back(Use(Idx[i], this));
79 LoadInst::LoadInst(Value *Ptr, const string &Name = "")
80 : MemAccessInst(cast<PointerType>(Ptr->getType())->getElementType(),
83 Operands.push_back(Use(Ptr, this));
87 //===----------------------------------------------------------------------===//
88 // StoreInst Implementation
89 //===----------------------------------------------------------------------===//
91 StoreInst::StoreInst(Value *Val, Value *Ptr, const vector<Value*> &Idx,
92 const string &Name = "")
93 : MemAccessInst(Type::VoidTy, Store, Name) {
94 assert(getIndexedType(Ptr->getType(), Idx) && "Store operands invalid!");
96 Operands.reserve(2+Idx.size());
97 Operands.push_back(Use(Val, this));
98 Operands.push_back(Use(Ptr, this));
100 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
101 Operands.push_back(Use(Idx[i], this));
104 StoreInst::StoreInst(Value *Val, Value *Ptr, const string &Name = "")
105 : MemAccessInst(Type::VoidTy, Store, Name) {
108 Operands.push_back(Use(Val, this));
109 Operands.push_back(Use(Ptr, this));
113 //===----------------------------------------------------------------------===//
114 // GetElementPtrInst Implementation
115 //===----------------------------------------------------------------------===//
117 GetElementPtrInst::GetElementPtrInst(Value *Ptr, const vector<Value*> &Idx,
118 const string &Name = "")
119 : MemAccessInst(PointerType::get(checkType(getIndexedType(Ptr->getType(),
121 GetElementPtr, Name) {
122 assert(getIndexedType(Ptr->getType(), Idx, true) && "gep operands invalid!");
123 Operands.reserve(1+Idx.size());
124 Operands.push_back(Use(Ptr, this));
126 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
127 Operands.push_back(Use(Idx[i], this));
130 bool GetElementPtrInst::isStructSelector() const {
131 return ((PointerType*)Operands[0]->getType())->getElementType()->isStructType();