Remove some gross stuff
[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<ConstPoolVal*> &Idx,
22                                           bool AllowStructLeaf = false) {
23   if (!Ptr->isPointerType()) return 0;   // Type isn't a pointer type!
24  
25   // Get the type pointed to...
26   Ptr = ((const PointerType*)Ptr)->getValueType();
27   
28   if (Ptr->isStructType()) {
29     unsigned CurIDX = 0;
30     while (Ptr->isStructType()) {
31       if (Idx.size() == CurIDX) 
32         return AllowStructLeaf ? Ptr : 0;   // Can't load a whole structure!?!?
33       if (Idx[CurIDX]->getType() != Type::UByteTy) return 0; // Illegal idx
34       unsigned NextIdx = ((ConstPoolUInt*)Idx[CurIDX++])->getValue();
35       
36       const StructType *ST = (const StructType *)Ptr;
37       Ptr = ST->getElementTypes()[NextIdx];
38     }
39     return Ptr;
40   } else if (Ptr->isArrayType()) {
41     assert(0 && "Loading from arrays not implemented yet!");
42   } else {
43     return (Idx.size() == 0) ? Ptr : 0;  // Load directly through ptr
44   }
45 }
46
47 unsigned int
48 MemAccessInst::getIndexedOfsetForTarget(const Type *Ptr, 
49                                         const vector<ConstPoolVal*> &Idx,
50                                         const TargetMachine& targetMachine)
51 {
52   if (!Ptr->isPointerType())
53     return 0;                           // Type isn't a pointer type!
54  
55   unsigned int curOffset = 0;
56   
57   // Get the type pointed to...
58   Ptr = ((const PointerType*) Ptr)->getValueType();
59   
60   if (Ptr->isStructType()) {
61     unsigned CurIDX = 0;                // which element of Idx vector
62     while (Ptr->isStructType()) {
63       const StructType * SPtr = (StructType *) Ptr;
64       
65       if (Idx.size() == CurIDX) 
66         break;
67       
68       assert (Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
69       unsigned NextIdx = ((ConstPoolUInt*)Idx[CurIDX++])->getValue();
70       
71       // add the offset for the current element
72       curOffset += SPtr->getElementOffset(NextIdx, targetMachine);
73       
74       // and update Ptr to refer to current element
75       Ptr = SPtr->getElementTypes()[NextIdx];
76     }
77     return curOffset;
78   } else if (Ptr->isArrayType()) {
79     assert(0 && "Loading from arrays not implemented yet!");
80   } else {
81     assert (Idx.size() == 0 && "Indexing type that is not struct or array?");
82     return 0;                           // Load directly through ptr
83   }
84 }
85   
86
87 //===----------------------------------------------------------------------===//
88 //                           LoadInst Implementation
89 //===----------------------------------------------------------------------===//
90
91 LoadInst::LoadInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
92                    const string &Name = "")
93   : MemAccessInst(getIndexedType(Ptr->getType(), Idx), Load, Idx, Name) {
94   assert(getIndexedType(Ptr->getType(), Idx) && "Load operands invalid!");
95   Operands.reserve(1+Idx.size());
96   Operands.push_back(Use(Ptr, this));
97   
98   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
99     Operands.push_back(Use(Idx[i], this));
100   
101 }
102
103
104 //===----------------------------------------------------------------------===//
105 //                           StoreInst Implementation
106 //===----------------------------------------------------------------------===//
107
108 StoreInst::StoreInst(Value *Val, Value *Ptr, const vector<ConstPoolVal*> &Idx,
109                      const string &Name = "")
110   : MemAccessInst(Type::VoidTy, Store, Idx, Name) {
111   assert(getIndexedType(Ptr->getType(), Idx) && "Store operands invalid!");
112   
113   Operands.reserve(2+Idx.size());
114   Operands.push_back(Use(Val, this));
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
122 //===----------------------------------------------------------------------===//
123 //                       GetElementPtrInst Implementation
124 //===----------------------------------------------------------------------===//
125
126 GetElementPtrInst::GetElementPtrInst(Value *Ptr, 
127                                      const vector<ConstPoolVal*> &Idx,
128                                      const string &Name = "")
129   : MemAccessInst(PointerType::getPointerType(getIndexedType(Ptr->getType(),
130                                                              Idx, true)),
131                   GetElementPtr, Idx, Name) {
132   assert(getIndexedType(Ptr->getType(), Idx, true) && "gep operands invalid!");
133   Operands.reserve(1+Idx.size());
134   Operands.push_back(Use(Ptr, this));
135
136   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
137     Operands.push_back(Use(Idx[i], this));
138 }
139
140 bool GetElementPtrInst::isStructSelector() const {
141   return ((PointerType*)Operands[0]->getType())->getValueType()->isStructType();
142 }