c61961b58e3574028ee4aacc9f6d11e2333f867b
[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 //===----------------------------------------------------------------------===//
10 //                        MemAccessInst Implementation
11 //===----------------------------------------------------------------------===//
12
13 // getIndexedType - Returns the type of the element that would be loaded with
14 // a load instruction with the specified parameters.
15 //
16 // A null type is returned if the indices are invalid for the specified 
17 // pointer type.
18 //
19 const Type* MemAccessInst::getIndexedType(const Type *Ptr, 
20                                           const vector<Value*> &Idx,
21                                           bool AllowCompositeLeaf = false) {
22   if (!Ptr->isPointerType()) return 0;   // Type isn't a pointer type!
23  
24   // Get the type pointed to...
25   Ptr = cast<PointerType>(Ptr)->getElementType();
26   
27   unsigned CurIDX = 0;
28   while (const CompositeType *ST = dyn_cast<CompositeType>(Ptr)) {
29     if (Idx.size() == CurIDX)
30       return AllowCompositeLeaf ? Ptr : 0;   // Can't load a whole structure!?!?
31
32     Value *Index = Idx[CurIDX++];
33     if (!ST->indexValid(Index)) return 0;
34     Ptr = ST->getTypeAtIndex(Index);
35   }
36   return CurIDX == Idx.size() ? Ptr : 0;
37 }
38
39
40 #if 1
41 #include "llvm/ConstantVals.h"
42 const vector<Constant*> MemAccessInst::getIndicesBROKEN() const {
43   cerr << "MemAccessInst::getIndices() does not do what you want it to.  Talk"
44        << " to Chris about this.  We can phase it out after the paper.\n";
45
46   vector<Constant*> RetVal;
47
48   // THIS CODE WILL FAIL IF A NON CONSTANT INDEX IS USED AS AN ARRAY INDEX
49   // THIS IS WHY YOU SHOULD NOT USE THIS FUNCTION ANY MORE!!!
50   for (unsigned i = getFirstIndexOperandNumber(); i < getNumOperands(); ++i)
51     RetVal.push_back(cast<Constant>(getOperand(i)));
52
53   return RetVal;
54 }
55 #endif
56
57 //===----------------------------------------------------------------------===//
58 //                           LoadInst Implementation
59 //===----------------------------------------------------------------------===//
60
61 LoadInst::LoadInst(Value *Ptr, const vector<Value*> &Idx,
62                    const string &Name = "")
63   : MemAccessInst(getIndexedType(Ptr->getType(), Idx), Load, Name) {
64   assert(getIndexedType(Ptr->getType(), Idx) && "Load operands invalid!");
65   Operands.reserve(1+Idx.size());
66   Operands.push_back(Use(Ptr, this));
67   
68   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
69     Operands.push_back(Use(Idx[i], this));
70   
71 }
72
73 LoadInst::LoadInst(Value *Ptr, const string &Name = "")
74   : MemAccessInst(cast<PointerType>(Ptr->getType())->getElementType(),
75                   Load, Name) {
76   Operands.reserve(1);
77   Operands.push_back(Use(Ptr, this));
78 }
79
80
81 //===----------------------------------------------------------------------===//
82 //                           StoreInst Implementation
83 //===----------------------------------------------------------------------===//
84
85 StoreInst::StoreInst(Value *Val, Value *Ptr, const vector<Value*> &Idx,
86                      const string &Name = "")
87   : MemAccessInst(Type::VoidTy, Store, Name) {
88   assert(getIndexedType(Ptr->getType(), Idx) && "Store operands invalid!");
89   
90   Operands.reserve(2+Idx.size());
91   Operands.push_back(Use(Val, this));
92   Operands.push_back(Use(Ptr, this));
93
94   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
95     Operands.push_back(Use(Idx[i], this));
96 }
97
98 StoreInst::StoreInst(Value *Val, Value *Ptr, const string &Name = "")
99   : MemAccessInst(Type::VoidTy, Store, Name) {
100   
101   Operands.reserve(2);
102   Operands.push_back(Use(Val, this));
103   Operands.push_back(Use(Ptr, this));
104 }
105
106
107 //===----------------------------------------------------------------------===//
108 //                       GetElementPtrInst Implementation
109 //===----------------------------------------------------------------------===//
110
111 GetElementPtrInst::GetElementPtrInst(Value *Ptr, const vector<Value*> &Idx,
112                                      const string &Name = "")
113   : MemAccessInst(PointerType::get(getIndexedType(Ptr->getType(), Idx, true)),
114                   GetElementPtr, Name) {
115   assert(getIndexedType(Ptr->getType(), Idx, true) && "gep operands invalid!");
116   Operands.reserve(1+Idx.size());
117   Operands.push_back(Use(Ptr, this));
118
119   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
120     Operands.push_back(Use(Idx[i], this));
121 }
122
123 bool GetElementPtrInst::isStructSelector() const {
124   return ((PointerType*)Operands[0]->getType())->getElementType()->isStructType();
125 }