* Assert that indices are valid for an indexing instruction.
[oota-llvm.git] / lib / VMCore / iMemory.cpp
1 //===-- iMemory.cpp - Implement Memory instructions --------------*- C++ -*--=//
2 //
3 // This file implements the various memory related classes defined in iMemory.h
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "llvm/iMemory.h"
8
9 static inline const Type *checkType(const Type *Ty) {
10   assert(Ty && "Invalid indices for type!");
11   return Ty;
12 }
13
14 //===----------------------------------------------------------------------===//
15 //                        MemAccessInst Implementation
16 //===----------------------------------------------------------------------===//
17
18 // getIndexedType - Returns the type of the element that would be loaded with
19 // a load instruction with the specified parameters.
20 //
21 // A null type is returned if the indices are invalid for the specified 
22 // pointer type.
23 //
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!
28
29   // Handle the special case of the empty set index set...
30   if (Idx.empty()) return cast<PointerType>(Ptr)->getElementType();
31  
32   unsigned CurIDX = 0;
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!?!?
37     }
38
39     Value *Index = Idx[CurIDX++];
40     if (!CT->indexValid(Index)) return 0;
41     Ptr = CT->getTypeAtIndex(Index);
42   }
43   return CurIDX == Idx.size() ? Ptr : 0;
44 }
45
46
47 #if 1
48 #include "llvm/ConstantVals.h"
49 const vector<Constant*> MemAccessInst::getIndicesBROKEN() const {
50   cerr << "FIXME: MemAccessInst::getIndices() should not be used!\n";
51
52   vector<Constant*> RetVal;
53
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)));
58
59   return RetVal;
60 }
61 #endif
62
63 //===----------------------------------------------------------------------===//
64 //                           LoadInst Implementation
65 //===----------------------------------------------------------------------===//
66
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));
73   
74   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
75     Operands.push_back(Use(Idx[i], this));
76   
77 }
78
79 LoadInst::LoadInst(Value *Ptr, const string &Name = "")
80   : MemAccessInst(cast<PointerType>(Ptr->getType())->getElementType(),
81                   Load, Name) {
82   Operands.reserve(1);
83   Operands.push_back(Use(Ptr, this));
84 }
85
86
87 //===----------------------------------------------------------------------===//
88 //                           StoreInst Implementation
89 //===----------------------------------------------------------------------===//
90
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!");
95   
96   Operands.reserve(2+Idx.size());
97   Operands.push_back(Use(Val, this));
98   Operands.push_back(Use(Ptr, this));
99
100   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
101     Operands.push_back(Use(Idx[i], this));
102 }
103
104 StoreInst::StoreInst(Value *Val, Value *Ptr, const string &Name = "")
105   : MemAccessInst(Type::VoidTy, Store, Name) {
106   
107   Operands.reserve(2);
108   Operands.push_back(Use(Val, this));
109   Operands.push_back(Use(Ptr, this));
110 }
111
112
113 //===----------------------------------------------------------------------===//
114 //                       GetElementPtrInst Implementation
115 //===----------------------------------------------------------------------===//
116
117 GetElementPtrInst::GetElementPtrInst(Value *Ptr, const vector<Value*> &Idx,
118                                      const string &Name = "")
119   : MemAccessInst(PointerType::get(checkType(getIndexedType(Ptr->getType(),
120                                                             Idx, true))),
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));
125
126   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
127     Operands.push_back(Use(Idx[i], this));
128 }
129
130 bool GetElementPtrInst::isStructSelector() const {
131   return ((PointerType*)Operands[0]->getType())->getElementType()->isStructType();
132 }