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
47 //===----------------------------------------------------------------------===//
48 // LoadInst Implementation
49 //===----------------------------------------------------------------------===//
51 LoadInst::LoadInst(Value *Ptr, const vector<ConstPoolVal*> &Idx,
52 const string &Name = "")
53 : MemAccessInst(getIndexedType(Ptr->getType(), Idx), Load, Idx, Name) {
54 assert(getIndexedType(Ptr->getType(), Idx) && "Load operands invalid!");
55 Operands.reserve(1+Idx.size());
56 Operands.push_back(Use(Ptr, this));
58 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
59 Operands.push_back(Use(Idx[i], this));
63 LoadInst::LoadInst(Value *Ptr, const string &Name = "")
64 : MemAccessInst(cast<PointerType>(Ptr->getType())->getValueType(),
65 Load, vector<ConstPoolVal*>(), Name) {
67 Operands.push_back(Use(Ptr, this));
71 //===----------------------------------------------------------------------===//
72 // StoreInst Implementation
73 //===----------------------------------------------------------------------===//
75 StoreInst::StoreInst(Value *Val, Value *Ptr, const vector<ConstPoolVal*> &Idx,
76 const string &Name = "")
77 : MemAccessInst(Type::VoidTy, Store, Idx, Name) {
78 assert(getIndexedType(Ptr->getType(), Idx) && "Store operands invalid!");
80 Operands.reserve(2+Idx.size());
81 Operands.push_back(Use(Val, this));
82 Operands.push_back(Use(Ptr, this));
84 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
85 Operands.push_back(Use(Idx[i], this));
88 StoreInst::StoreInst(Value *Val, Value *Ptr, const string &Name = "")
89 : MemAccessInst(Type::VoidTy, Store, vector<ConstPoolVal*>(), Name) {
92 Operands.push_back(Use(Val, this));
93 Operands.push_back(Use(Ptr, this));
97 //===----------------------------------------------------------------------===//
98 // GetElementPtrInst Implementation
99 //===----------------------------------------------------------------------===//
101 GetElementPtrInst::GetElementPtrInst(Value *Ptr,
102 const vector<ConstPoolVal*> &Idx,
103 const string &Name = "")
104 : MemAccessInst(PointerType::get(getIndexedType(Ptr->getType(), Idx, true)),
105 GetElementPtr, Idx, Name) {
106 assert(getIndexedType(Ptr->getType(), Idx, true) && "gep operands invalid!");
107 Operands.reserve(1+Idx.size());
108 Operands.push_back(Use(Ptr, this));
110 for (unsigned i = 0, E = Idx.size(); i != E; ++i)
111 Operands.push_back(Use(Idx[i], this));
114 bool GetElementPtrInst::isStructSelector() const {
115 return ((PointerType*)Operands[0]->getType())->getValueType()->isStructType();