Added LLVM project notice to the top of every C++ source file.
[oota-llvm.git] / lib / VMCore / iMemory.cpp
1 //===-- iMemory.cpp - Implement Memory instructions -----------------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the various memory related classes defined in iMemory.h
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/iMemory.h"
15 #include "llvm/Constants.h"
16 #include "llvm/DerivedTypes.h"
17
18 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
19                                const std::string &Name, Instruction *InsertBef)
20   : Instruction(PointerType::get(Ty), iTy, Name, InsertBef) {
21
22   // ArraySize defaults to 1.
23   if (!ArraySize) ArraySize = ConstantUInt::get(Type::UIntTy, 1);
24
25   Operands.reserve(1);
26   assert(ArraySize->getType() == Type::UIntTy &&
27          "Malloc/Allocation array size != UIntTy!");
28
29   Operands.push_back(Use(ArraySize, this));
30 }
31
32 bool AllocationInst::isArrayAllocation() const {
33   return getOperand(0) != ConstantUInt::get(Type::UIntTy, 1);
34 }
35
36 const Type *AllocationInst::getAllocatedType() const {
37   return getType()->getElementType();
38 }
39
40 AllocaInst::AllocaInst(const AllocaInst &AI)
41   : AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0),
42                    Instruction::Alloca) {
43 }
44
45 MallocInst::MallocInst(const MallocInst &MI)
46   : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
47                    Instruction::Malloc) {
48 }
49
50 //===----------------------------------------------------------------------===//
51 //                             FreeInst Implementation
52 //===----------------------------------------------------------------------===//
53
54 FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore)
55   : Instruction(Type::VoidTy, Free, "", InsertBefore) {
56   assert(isa<PointerType>(Ptr->getType()) && "Can't free nonpointer!");
57   Operands.reserve(1);
58   Operands.push_back(Use(Ptr, this));
59 }
60
61
62 //===----------------------------------------------------------------------===//
63 //                           LoadInst Implementation
64 //===----------------------------------------------------------------------===//
65
66 LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef)
67   : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
68                 Load, Name, InsertBef), Volatile(false) {
69   Operands.reserve(1);
70   Operands.push_back(Use(Ptr, this));
71 }
72
73 LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
74                    Instruction *InsertBef)
75   : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
76                 Load, Name, InsertBef), Volatile(isVolatile) {
77   Operands.reserve(1);
78   Operands.push_back(Use(Ptr, this));
79 }
80
81 //===----------------------------------------------------------------------===//
82 //                           StoreInst Implementation
83 //===----------------------------------------------------------------------===//
84
85 StoreInst::StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore)
86   : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(false) {
87   
88   Operands.reserve(2);
89   Operands.push_back(Use(Val, this));
90   Operands.push_back(Use(Ptr, this));
91 }
92
93 StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, 
94                      Instruction *InsertBefore)
95   : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(isVolatile) {
96   
97   Operands.reserve(2);
98   Operands.push_back(Use(Val, this));
99   Operands.push_back(Use(Ptr, this));
100 }
101
102
103 //===----------------------------------------------------------------------===//
104 //                       GetElementPtrInst Implementation
105 //===----------------------------------------------------------------------===//
106
107 // checkType - Simple wrapper function to give a better assertion failure
108 // message on bad indexes for a gep instruction.
109 //
110 static inline const Type *checkType(const Type *Ty) {
111   assert(Ty && "Invalid indices for type!");
112   return Ty;
113 }
114
115 GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
116                                      const std::string &Name, Instruction *InBe)
117   : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),
118                                                             Idx, true))),
119                   GetElementPtr, Name, InBe) {
120   Operands.reserve(1+Idx.size());
121   Operands.push_back(Use(Ptr, this));
122
123   for (unsigned i = 0, E = Idx.size(); i != E; ++i)
124     Operands.push_back(Use(Idx[i], this));
125 }
126
127 // getIndexedType - Returns the type of the element that would be loaded with
128 // a load instruction with the specified parameters.
129 //
130 // A null type is returned if the indices are invalid for the specified 
131 // pointer type.
132 //
133 const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, 
134                                               const std::vector<Value*> &Idx,
135                                               bool AllowCompositeLeaf) {
136   if (!isa<PointerType>(Ptr)) return 0;   // Type isn't a pointer type!
137
138   // Handle the special case of the empty set index set...
139   if (Idx.empty()) return cast<PointerType>(Ptr)->getElementType();
140  
141   unsigned CurIdx = 0;
142   while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
143     if (Idx.size() == CurIdx) {
144       if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr;
145       return 0;   // Can't load a whole structure or array!?!?
146     }
147
148     Value *Index = Idx[CurIdx++];
149     if (isa<PointerType>(CT) && CurIdx != 1)
150       return 0;  // Can only index into pointer types at the first index!
151     if (!CT->indexValid(Index)) return 0;
152     Ptr = CT->getTypeAtIndex(Index);
153   }
154   return CurIdx == Idx.size() ? Ptr : 0;
155 }