LLVM  4.0.0
Loads.cpp
Go to the documentation of this file.
1 //===- Loads.cpp - Local load analysis ------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines simple local analyses for load instructions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Analysis/Loads.h"
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/GlobalAlias.h"
19 #include "llvm/IR/GlobalVariable.h"
20 #include "llvm/IR/IntrinsicInst.h"
21 #include "llvm/IR/LLVMContext.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/IR/Operator.h"
24 #include "llvm/IR/Statepoint.h"
25 
26 using namespace llvm;
27 
28 static bool isAligned(const Value *Base, const APInt &Offset, unsigned Align,
29  const DataLayout &DL) {
30  APInt BaseAlign(Offset.getBitWidth(), Base->getPointerAlignment(DL));
31 
32  if (!BaseAlign) {
33  Type *Ty = Base->getType()->getPointerElementType();
34  if (!Ty->isSized())
35  return false;
36  BaseAlign = DL.getABITypeAlignment(Ty);
37  }
38 
39  APInt Alignment(Offset.getBitWidth(), Align);
40 
41  assert(Alignment.isPowerOf2() && "must be a power of 2!");
42  return BaseAlign.uge(Alignment) && !(Offset & (Alignment-1));
43 }
44 
45 static bool isAligned(const Value *Base, unsigned Align, const DataLayout &DL) {
46  Type *Ty = Base->getType();
47  assert(Ty->isSized() && "must be sized");
49  return isAligned(Base, Offset, Align, DL);
50 }
51 
52 /// Test if V is always a pointer to allocated and suitably aligned memory for
53 /// a simple load or store.
55  const Value *V, unsigned Align, const APInt &Size, const DataLayout &DL,
56  const Instruction *CtxI, const DominatorTree *DT,
58  // Already visited? Bail out, we've likely hit unreachable code.
59  if (!Visited.insert(V).second)
60  return false;
61 
62  // Note that it is not safe to speculate into a malloc'd region because
63  // malloc may return null.
64 
65  // bitcast instructions are no-ops as far as dereferenceability is concerned.
66  if (const BitCastOperator *BC = dyn_cast<BitCastOperator>(V))
67  return isDereferenceableAndAlignedPointer(BC->getOperand(0), Align, Size,
68  DL, CtxI, DT, Visited);
69 
70  bool CheckForNonNull = false;
71  APInt KnownDerefBytes(Size.getBitWidth(),
72  V->getPointerDereferenceableBytes(DL, CheckForNonNull));
73  if (KnownDerefBytes.getBoolValue()) {
74  if (KnownDerefBytes.uge(Size))
75  if (!CheckForNonNull || isKnownNonNullAt(V, CtxI, DT))
76  return isAligned(V, Align, DL);
77  }
78 
79  // For GEPs, determine if the indexing lands within the allocated object.
80  if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
81  const Value *Base = GEP->getPointerOperand();
82 
83  APInt Offset(DL.getPointerTypeSizeInBits(GEP->getType()), 0);
84  if (!GEP->accumulateConstantOffset(DL, Offset) || Offset.isNegative() ||
85  !Offset.urem(APInt(Offset.getBitWidth(), Align)).isMinValue())
86  return false;
87 
88  // If the base pointer is dereferenceable for Offset+Size bytes, then the
89  // GEP (== Base + Offset) is dereferenceable for Size bytes. If the base
90  // pointer is aligned to Align bytes, and the Offset is divisible by Align
91  // then the GEP (== Base + Offset == k_0 * Align + k_1 * Align) is also
92  // aligned to Align bytes.
93 
94  // Offset and Size may have different bit widths if we have visited an
95  // addrspacecast, so we can't do arithmetic directly on the APInt values.
97  Base, Align, Offset + Size.sextOrTrunc(Offset.getBitWidth()),
98  DL, CtxI, DT, Visited);
99  }
100 
101  // For gc.relocate, look through relocations
102  if (const GCRelocateInst *RelocateInst = dyn_cast<GCRelocateInst>(V))
104  RelocateInst->getDerivedPtr(), Align, Size, DL, CtxI, DT, Visited);
105 
106  if (const AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(V))
107  return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Align, Size,
108  DL, CtxI, DT, Visited);
109 
110  if (auto CS = ImmutableCallSite(V))
111  if (const Value *RV = CS.getReturnedArgOperand())
112  return isDereferenceableAndAlignedPointer(RV, Align, Size, DL, CtxI, DT,
113  Visited);
114 
115  // If we don't know, assume the worst.
116  return false;
117 }
118 
119 bool llvm::isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
120  const DataLayout &DL,
121  const Instruction *CtxI,
122  const DominatorTree *DT) {
123  // When dereferenceability information is provided by a dereferenceable
124  // attribute, we know exactly how many bytes are dereferenceable. If we can
125  // determine the exact offset to the attributed variable, we can use that
126  // information here.
127  Type *VTy = V->getType();
128  Type *Ty = VTy->getPointerElementType();
129 
130  // Require ABI alignment for loads without alignment specification
131  if (Align == 0)
132  Align = DL.getABITypeAlignment(Ty);
133 
134  if (!Ty->isSized())
135  return false;
136 
139  V, Align, APInt(DL.getTypeSizeInBits(VTy), DL.getTypeStoreSize(Ty)), DL,
140  CtxI, DT, Visited);
141 }
142 
144  const Instruction *CtxI,
145  const DominatorTree *DT) {
146  return isDereferenceableAndAlignedPointer(V, 1, DL, CtxI, DT);
147 }
148 
149 /// \brief Test if A and B will obviously have the same value.
150 ///
151 /// This includes recognizing that %t0 and %t1 will have the same
152 /// value in code like this:
153 /// \code
154 /// %t0 = getelementptr \@a, 0, 3
155 /// store i32 0, i32* %t0
156 /// %t1 = getelementptr \@a, 0, 3
157 /// %t2 = load i32* %t1
158 /// \endcode
159 ///
160 static bool AreEquivalentAddressValues(const Value *A, const Value *B) {
161  // Test if the values are trivially equivalent.
162  if (A == B)
163  return true;
164 
165  // Test if the values come from identical arithmetic instructions.
166  // Use isIdenticalToWhenDefined instead of isIdenticalTo because
167  // this function is only used when one address use dominates the
168  // other, which means that they'll always either have the same
169  // value or one of them will have an undefined value.
170  if (isa<BinaryOperator>(A) || isa<CastInst>(A) || isa<PHINode>(A) ||
171  isa<GetElementPtrInst>(A))
172  if (const Instruction *BI = dyn_cast<Instruction>(B))
173  if (cast<Instruction>(A)->isIdenticalToWhenDefined(BI))
174  return true;
175 
176  // Otherwise they may not be equivalent.
177  return false;
178 }
179 
180 /// \brief Check if executing a load of this pointer value cannot trap.
181 ///
182 /// If DT and ScanFrom are specified this method performs context-sensitive
183 /// analysis and returns true if it is safe to load immediately before ScanFrom.
184 ///
185 /// If it is not obviously safe to load from the specified pointer, we do
186 /// a quick local scan of the basic block containing \c ScanFrom, to determine
187 /// if the address is already accessed.
188 ///
189 /// This uses the pointee type to determine how many bytes need to be safe to
190 /// load from the pointer.
191 bool llvm::isSafeToLoadUnconditionally(Value *V, unsigned Align,
192  const DataLayout &DL,
193  Instruction *ScanFrom,
194  const DominatorTree *DT) {
195  // Zero alignment means that the load has the ABI alignment for the target
196  if (Align == 0)
198  assert(isPowerOf2_32(Align));
199 
200  // If DT is not specified we can't make context-sensitive query
201  const Instruction* CtxI = DT ? ScanFrom : nullptr;
202  if (isDereferenceableAndAlignedPointer(V, Align, DL, CtxI, DT))
203  return true;
204 
205  int64_t ByteOffset = 0;
206  Value *Base = V;
207  Base = GetPointerBaseWithConstantOffset(V, ByteOffset, DL);
208 
209  if (ByteOffset < 0) // out of bounds
210  return false;
211 
212  Type *BaseType = nullptr;
213  unsigned BaseAlign = 0;
214  if (const AllocaInst *AI = dyn_cast<AllocaInst>(Base)) {
215  // An alloca is safe to load from as load as it is suitably aligned.
216  BaseType = AI->getAllocatedType();
217  BaseAlign = AI->getAlignment();
218  } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
219  // Global variables are not necessarily safe to load from if they are
220  // interposed arbitrarily. Their size may change or they may be weak and
221  // require a test to determine if they were in fact provided.
222  if (!GV->isInterposable()) {
223  BaseType = GV->getType()->getElementType();
224  BaseAlign = GV->getAlignment();
225  }
226  }
227 
228  PointerType *AddrTy = cast<PointerType>(V->getType());
229  uint64_t LoadSize = DL.getTypeStoreSize(AddrTy->getElementType());
230 
231  // If we found a base allocated type from either an alloca or global variable,
232  // try to see if we are definitively within the allocated region. We need to
233  // know the size of the base type and the loaded type to do anything in this
234  // case.
235  if (BaseType && BaseType->isSized()) {
236  if (BaseAlign == 0)
237  BaseAlign = DL.getPrefTypeAlignment(BaseType);
238 
239  if (Align <= BaseAlign) {
240  // Check if the load is within the bounds of the underlying object.
241  if (ByteOffset + LoadSize <= DL.getTypeAllocSize(BaseType) &&
242  ((ByteOffset % Align) == 0))
243  return true;
244  }
245  }
246 
247  if (!ScanFrom)
248  return false;
249 
250  // Otherwise, be a little bit aggressive by scanning the local block where we
251  // want to check to see if the pointer is already being loaded or stored
252  // from/to. If so, the previous load or store would have already trapped,
253  // so there is no harm doing an extra load (also, CSE will later eliminate
254  // the load entirely).
255  BasicBlock::iterator BBI = ScanFrom->getIterator(),
256  E = ScanFrom->getParent()->begin();
257 
258  // We can at least always strip pointer casts even though we can't use the
259  // base here.
260  V = V->stripPointerCasts();
261 
262  while (BBI != E) {
263  --BBI;
264 
265  // If we see a free or a call which may write to memory (i.e. which might do
266  // a free) the pointer could be marked invalid.
267  if (isa<CallInst>(BBI) && BBI->mayWriteToMemory() &&
268  !isa<DbgInfoIntrinsic>(BBI))
269  return false;
270 
271  Value *AccessedPtr;
272  unsigned AccessedAlign;
273  if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
274  AccessedPtr = LI->getPointerOperand();
275  AccessedAlign = LI->getAlignment();
276  } else if (StoreInst *SI = dyn_cast<StoreInst>(BBI)) {
277  AccessedPtr = SI->getPointerOperand();
278  AccessedAlign = SI->getAlignment();
279  } else
280  continue;
281 
282  Type *AccessedTy = AccessedPtr->getType()->getPointerElementType();
283  if (AccessedAlign == 0)
284  AccessedAlign = DL.getABITypeAlignment(AccessedTy);
285  if (AccessedAlign < Align)
286  continue;
287 
288  // Handle trivial cases.
289  if (AccessedPtr == V)
290  return true;
291 
292  if (AreEquivalentAddressValues(AccessedPtr->stripPointerCasts(), V) &&
293  LoadSize <= DL.getTypeStoreSize(AccessedTy))
294  return true;
295  }
296  return false;
297 }
298 
299 /// DefMaxInstsToScan - the default number of maximum instructions
300 /// to scan in the block, used by FindAvailableLoadedValue().
301 /// FindAvailableLoadedValue() was introduced in r60148, to improve jump
302 /// threading in part by eliminating partially redundant loads.
303 /// At that point, the value of MaxInstsToScan was already set to '6'
304 /// without documented explanation.
306 llvm::DefMaxInstsToScan("available-load-scan-limit", cl::init(6), cl::Hidden,
307  cl::desc("Use this to specify the default maximum number of instructions "
308  "to scan backward from a given instruction, when searching for "
309  "available loaded value"));
310 
312  BasicBlock *ScanBB,
313  BasicBlock::iterator &ScanFrom,
314  unsigned MaxInstsToScan,
315  AliasAnalysis *AA, bool *IsLoadCSE) {
316  if (MaxInstsToScan == 0)
317  MaxInstsToScan = ~0U;
318 
319  Value *Ptr = Load->getPointerOperand();
320  Type *AccessTy = Load->getType();
321 
322  // We can never remove a volatile load
323  if (Load->isVolatile())
324  return nullptr;
325 
326  // Anything stronger than unordered is currently unimplemented.
327  if (!Load->isUnordered())
328  return nullptr;
329 
330  const DataLayout &DL = ScanBB->getModule()->getDataLayout();
331 
332  // Try to get the store size for the type.
333  uint64_t AccessSize = DL.getTypeStoreSize(AccessTy);
334 
335  Value *StrippedPtr = Ptr->stripPointerCasts();
336 
337  while (ScanFrom != ScanBB->begin()) {
338  // We must ignore debug info directives when counting (otherwise they
339  // would affect codegen).
340  Instruction *Inst = &*--ScanFrom;
341  if (isa<DbgInfoIntrinsic>(Inst))
342  continue;
343 
344  // Restore ScanFrom to expected value in case next test succeeds
345  ScanFrom++;
346 
347  // Don't scan huge blocks.
348  if (MaxInstsToScan-- == 0)
349  return nullptr;
350 
351  --ScanFrom;
352  // If this is a load of Ptr, the loaded value is available.
353  // (This is true even if the load is volatile or atomic, although
354  // those cases are unlikely.)
355  if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
357  LI->getPointerOperand()->stripPointerCasts(), StrippedPtr) &&
358  CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) {
359 
360  // We can value forward from an atomic to a non-atomic, but not the
361  // other way around.
362  if (LI->isAtomic() < Load->isAtomic())
363  return nullptr;
364 
365  if (IsLoadCSE)
366  *IsLoadCSE = true;
367  return LI;
368  }
369 
370  if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
371  Value *StorePtr = SI->getPointerOperand()->stripPointerCasts();
372  // If this is a store through Ptr, the value is available!
373  // (This is true even if the store is volatile or atomic, although
374  // those cases are unlikely.)
375  if (AreEquivalentAddressValues(StorePtr, StrippedPtr) &&
376  CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(),
377  AccessTy, DL)) {
378 
379  // We can value forward from an atomic to a non-atomic, but not the
380  // other way around.
381  if (SI->isAtomic() < Load->isAtomic())
382  return nullptr;
383 
384  if (IsLoadCSE)
385  *IsLoadCSE = false;
386  return SI->getOperand(0);
387  }
388 
389  // If both StrippedPtr and StorePtr reach all the way to an alloca or
390  // global and they are different, ignore the store. This is a trivial form
391  // of alias analysis that is important for reg2mem'd code.
392  if ((isa<AllocaInst>(StrippedPtr) || isa<GlobalVariable>(StrippedPtr)) &&
393  (isa<AllocaInst>(StorePtr) || isa<GlobalVariable>(StorePtr)) &&
394  StrippedPtr != StorePtr)
395  continue;
396 
397  // If we have alias analysis and it says the store won't modify the loaded
398  // value, ignore the store.
399  if (AA && (AA->getModRefInfo(SI, StrippedPtr, AccessSize) & MRI_Mod) == 0)
400  continue;
401 
402  // Otherwise the store that may or may not alias the pointer, bail out.
403  ++ScanFrom;
404  return nullptr;
405  }
406 
407  // If this is some other instruction that may clobber Ptr, bail out.
408  if (Inst->mayWriteToMemory()) {
409  // If alias analysis claims that it really won't modify the load,
410  // ignore it.
411  if (AA &&
412  (AA->getModRefInfo(Inst, StrippedPtr, AccessSize) & MRI_Mod) == 0)
413  continue;
414 
415  // May modify the pointer, bail out.
416  ++ScanFrom;
417  return nullptr;
418  }
419  }
420 
421  // Got to the start of the block, we didn't find it, but are done for this
422  // block.
423  return nullptr;
424 }
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:102
unsigned getPrefTypeAlignment(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
Definition: DataLayout.cpp:699
cl::opt< unsigned > DefMaxInstsToScan
The default number of maximum instructions to scan in the block, used by FindAvailableLoadedValue().
An instruction for reading from memory.
Definition: Instructions.h:164
Hexagon Common GEP
Type * getElementType() const
Definition: DerivedTypes.h:462
bool isSafeToLoadUnconditionally(Value *V, unsigned Align, const DataLayout &DL, Instruction *ScanFrom=nullptr, const DominatorTree *DT=nullptr)
Return true if we know that executing a load from this value cannot trap.
Definition: Loads.cpp:191
static bool isAligned(const Value *Base, const APInt &Offset, unsigned Align, const DataLayout &DL)
Definition: Loads.cpp:28
The access modifies the value stored in memory.
Type * getPointerElementType() const
Definition: Type.h:358
static bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:345
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:228
bool isNegative() const
Determine sign of this APInt.
Definition: APInt.h:324
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
Definition: APInt.cpp:1865
This class represents a conversion between pointers from one address space to another.
unsigned getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition: Value.cpp:599
bool isUnordered() const
Definition: Instructions.h:264
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr it the function does no...
Definition: BasicBlock.cpp:116
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
An instruction for storing to memory.
Definition: Instructions.h:300
Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, AliasAnalysis *AA=nullptr, bool *IsLoadCSE=nullptr)
Scan backwards to see if we have the value of the given load available locally within a small number ...
Definition: Loads.cpp:311
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:96
bool isAtomic() const
Return true if this instruction has an AtomicOrdering of unordered or higher.
Class to represent pointers.
Definition: DerivedTypes.h:443
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:254
static bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, const APInt &Size, const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT, SmallPtrSetImpl< const Value * > &Visited)
Test if V is always a pointer to allocated and suitably aligned memory for a simple load or store...
Definition: Loads.cpp:54
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
Definition: MathExtras.h:399
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
Definition: DataLayout.h:399
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:368
uint32_t Offset
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1255
Value * getPointerOperand()
Definition: Instructions.h:270
self_iterator getIterator()
Definition: ilist_node.h:81
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:689
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:425
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:408
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:230
bool isVolatile() const
Return true if this is a load from a volatile memory location.
Definition: Instructions.h:218
Value * stripPointerCasts()
Strip off pointer casts, all-zero GEPs, and aliases.
Definition: Value.cpp:490
static bool AreEquivalentAddressValues(const Value *A, const Value *B)
Test if A and B will obviously have the same value.
Definition: Loads.cpp:160
Class for arbitrary precision integers.
Definition: APInt.h:77
ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
bool isMinValue() const
Determine if this is the smallest unsigned value.
Definition: APInt.h:366
bool isDereferenceablePointer(const Value *V, const DataLayout &DL, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr)
Return true if this is always a dereferenceable pointer.
Definition: Loads.cpp:143
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:384
unsigned getPointerDereferenceableBytes(const DataLayout &DL, bool &CanBeNull) const
Returns the number of bytes known to be dereferenceable for the pointer value.
Definition: Value.cpp:548
ImmutableCallSite - establish a view to a call site for examination.
Definition: CallSite.h:665
bool isKnownNonNullAt(const Value *V, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr)
Return true if this pointer couldn't possibly be null.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Definition: DataLayout.h:391
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represents calls to the gc.relocate intrinsic.
Definition: Statepoint.h:367
LLVM Value Representation.
Definition: Value.h:71
APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition: APInt.cpp:1007
uint64_t getTypeSizeInBits(Type *Ty) const
Size examples:
Definition: DataLayout.h:533
bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, const DataLayout &DL, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr)
Returns true if V is always a dereferenceable pointer with alignment greater or equal than requested...
Definition: Loads.cpp:119
int * Ptr
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
const BasicBlock * getParent() const
Definition: Instruction.h:62
an instruction to allocate memory on the stack
Definition: Instructions.h:60