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"
9 //===----------------------------------------------------------------------===//
10 // MemAccessInst Implementation
11 //===----------------------------------------------------------------------===//
13 // getIndexedType - Returns the type of the element that would be loaded with
14 // a load instruction with the specified parameters.
16 // A null type is returned if the indices are invalid for the specified
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!
24 // Get the type pointed to...
25 Ptr = cast<PointerType>(Ptr)->getValueType();
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!?!?
32 Value *Index = Idx[CurIDX++];
33 if (!ST->indexValid(Index)) return 0;
34 Ptr = ST->getTypeAtIndex(Index);
36 return CurIDX == Idx.size() ? Ptr : 0;
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";
46 vector<Constant*> RetVal;
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)));
57 //===----------------------------------------------------------------------===//
58 // LoadInst Implementation
59 //===----------------------------------------------------------------------===//
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));
68 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
69 Operands.push_back(Use(Idx[i], this));
73 LoadInst::LoadInst(Value *Ptr, const string &Name = "")
74 : MemAccessInst(cast<PointerType>(Ptr->getType())->getValueType(),
77 Operands.push_back(Use(Ptr, this));
81 //===----------------------------------------------------------------------===//
82 // StoreInst Implementation
83 //===----------------------------------------------------------------------===//
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!");
90 Operands.reserve(2+Idx.size());
91 Operands.push_back(Use(Val, this));
92 Operands.push_back(Use(Ptr, this));
94 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
95 Operands.push_back(Use(Idx[i], this));
98 StoreInst::StoreInst(Value *Val, Value *Ptr, const string &Name = "")
99 : MemAccessInst(Type::VoidTy, Store, Name) {
102 Operands.push_back(Use(Val, this));
103 Operands.push_back(Use(Ptr, this));
107 //===----------------------------------------------------------------------===//
108 // GetElementPtrInst Implementation
109 //===----------------------------------------------------------------------===//
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));
119 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
120 Operands.push_back(Use(Idx[i], this));
123 bool GetElementPtrInst::isStructSelector() const {
124 return ((PointerType*)Operands[0]->getType())->getValueType()->isStructType();