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