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"
8 #include "llvm/ConstPoolVals.h"
10 //===----------------------------------------------------------------------===//
11 // MemAccessInst Implementation
12 //===----------------------------------------------------------------------===//
14 // getIndexedType - Returns the type of the element that would be loaded with
15 // a load instruction with the specified parameters.
17 // A null type is returned if the indices are invalid for the specified
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!
25 // Get the type pointed to...
26 Ptr = ((const PointerType*)Ptr)->getValueType();
28 if (Ptr->isStructType()) {
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();
36 const StructType *ST = (const StructType *)Ptr;
37 Ptr = ST->getElementTypes()[NextIdx];
40 } else if (Ptr->isArrayType()) {
41 assert(0 && "Loading from arrays not implemented yet!");
43 return (Idx.size() == 0) ? Ptr : 0; // Load directly through ptr
48 MemAccessInst::getIndexedOfsetForTarget(const Type *Ptr,
49 const vector<ConstPoolVal*> &Idx,
50 const TargetMachine& targetMachine)
52 if (!Ptr->isPointerType())
53 return 0; // Type isn't a pointer type!
55 unsigned int curOffset = 0;
57 // Get the type pointed to...
58 Ptr = ((const PointerType*) Ptr)->getValueType();
60 if (Ptr->isStructType()) {
61 unsigned CurIDX = 0; // which element of Idx vector
62 while (Ptr->isStructType()) {
63 const StructType * SPtr = (StructType *) Ptr;
65 if (Idx.size() == CurIDX)
68 assert (Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
69 unsigned NextIdx = ((ConstPoolUInt*)Idx[CurIDX++])->getValue();
71 // add the offset for the current element
72 curOffset += SPtr->getElementOffset(NextIdx, targetMachine);
74 // and update Ptr to refer to current element
75 Ptr = SPtr->getElementTypes()[NextIdx];
78 } else if (Ptr->isArrayType()) {
79 assert(0 && "Loading from arrays not implemented yet!");
81 assert (Idx.size() == 0 && "Indexing type that is not struct or array?");
82 return 0; // Load directly through ptr
87 //===----------------------------------------------------------------------===//
88 // LoadInst Implementation
89 //===----------------------------------------------------------------------===//
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));
98 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
99 Operands.push_back(Use(Idx[i], this));
104 //===----------------------------------------------------------------------===//
105 // StoreInst Implementation
106 //===----------------------------------------------------------------------===//
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!");
113 Operands.reserve(2+Idx.size());
114 Operands.push_back(Use(Val, this));
115 Operands.push_back(Use(Ptr, this));
117 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
118 Operands.push_back(Use(Idx[i], this));
122 //===----------------------------------------------------------------------===//
123 // GetElementPtrInst Implementation
124 //===----------------------------------------------------------------------===//
126 GetElementPtrInst::GetElementPtrInst(Value *Ptr,
127 const vector<ConstPoolVal*> &Idx,
128 const string &Name = "")
129 : MemAccessInst(PointerType::getPointerType(getIndexedType(Ptr->getType(),
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));
136 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
137 Operands.push_back(Use(Idx[i], this));
140 bool GetElementPtrInst::isStructSelector() const {
141 return ((PointerType*)Operands[0]->getType())->getValueType()->isStructType();