LLVM  14.0.0git
StackLifetime.cpp
Go to the documentation of this file.
1 //===- StackLifetime.cpp - Alloca Lifetime Analysis -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/ADT/StringExtras.h"
15 #include "llvm/Config/llvm-config.h"
17 #include "llvm/IR/BasicBlock.h"
18 #include "llvm/IR/CFG.h"
19 #include "llvm/IR/InstIterator.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/IntrinsicInst.h"
22 #include "llvm/IR/Intrinsics.h"
23 #include "llvm/IR/User.h"
24 #include "llvm/IR/Value.h"
25 #include "llvm/Pass.h"
26 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Compiler.h"
29 #include "llvm/Support/Debug.h"
31 #include <algorithm>
32 #include <memory>
33 #include <tuple>
34 
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "stack-lifetime"
38 
41  const auto IT = AllocaNumbering.find(AI);
42  assert(IT != AllocaNumbering.end());
43  return LiveRanges[IT->second];
44 }
45 
47  return BlockInstRange.find(I->getParent()) != BlockInstRange.end();
48 }
49 
51  const Instruction *I) const {
52  const BasicBlock *BB = I->getParent();
53  auto ItBB = BlockInstRange.find(BB);
54  assert(ItBB != BlockInstRange.end() && "Unreachable is not expected");
55 
56  // Search the block for the first instruction following 'I'.
57  auto It = std::upper_bound(Instructions.begin() + ItBB->getSecond().first + 1,
58  Instructions.begin() + ItBB->getSecond().second, I,
59  [](const Instruction *L, const Instruction *R) {
60  return L->comesBefore(R);
61  });
62  --It;
63  unsigned InstNum = It - Instructions.begin();
64  return getLiveRange(AI).test(InstNum);
65 }
66 
67 // Returns unique alloca annotated by lifetime marker only if
68 // markers has the same size and points to the alloca start.
70  const DataLayout &DL) {
71  const AllocaInst *AI = findAllocaForValue(II.getArgOperand(1), true);
72  if (!AI)
73  return nullptr;
74 
75  auto AllocaSizeInBits = AI->getAllocationSizeInBits(DL);
76  if (!AllocaSizeInBits)
77  return nullptr;
78  int64_t AllocaSize = AllocaSizeInBits.getValue() / 8;
79 
80  auto *Size = dyn_cast<ConstantInt>(II.getArgOperand(0));
81  if (!Size)
82  return nullptr;
83  int64_t LifetimeSize = Size->getSExtValue();
84 
85  if (LifetimeSize != -1 && LifetimeSize != AllocaSize)
86  return nullptr;
87 
88  return AI;
89 }
90 
91 void StackLifetime::collectMarkers() {
92  InterestingAllocas.resize(NumAllocas);
94  BBMarkerSet;
95 
96  const DataLayout &DL = F.getParent()->getDataLayout();
97 
98  // Compute the set of start/end markers per basic block.
99  for (const BasicBlock *BB : depth_first(&F)) {
100  for (const Instruction &I : *BB) {
101  const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
102  if (!II || !II->isLifetimeStartOrEnd())
103  continue;
104  const AllocaInst *AI = findMatchingAlloca(*II, DL);
105  if (!AI) {
106  HasUnknownLifetimeStartOrEnd = true;
107  continue;
108  }
109  auto It = AllocaNumbering.find(AI);
110  if (It == AllocaNumbering.end())
111  continue;
112  auto AllocaNo = It->second;
113  bool IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
114  if (IsStart)
115  InterestingAllocas.set(AllocaNo);
116  BBMarkerSet[BB][II] = {AllocaNo, IsStart};
117  }
118  }
119 
120  // Compute instruction numbering. Only the following instructions are
121  // considered:
122  // * Basic block entries
123  // * Lifetime markers
124  // For each basic block, compute
125  // * the list of markers in the instruction order
126  // * the sets of allocas whose lifetime starts or ends in this BB
127  LLVM_DEBUG(dbgs() << "Instructions:\n");
128  for (const BasicBlock *BB : depth_first(&F)) {
129  LLVM_DEBUG(dbgs() << " " << Instructions.size() << ": BB " << BB->getName()
130  << "\n");
131  auto BBStart = Instructions.size();
132  Instructions.push_back(nullptr);
133 
134  BlockLifetimeInfo &BlockInfo =
135  BlockLiveness.try_emplace(BB, NumAllocas).first->getSecond();
136 
137  auto &BlockMarkerSet = BBMarkerSet[BB];
138  if (BlockMarkerSet.empty()) {
139  BlockInstRange[BB] = std::make_pair(BBStart, Instructions.size());
140  continue;
141  }
142 
143  auto ProcessMarker = [&](const IntrinsicInst *I, const Marker &M) {
144  LLVM_DEBUG(dbgs() << " " << Instructions.size() << ": "
145  << (M.IsStart ? "start " : "end ") << M.AllocaNo
146  << ", " << *I << "\n");
147 
148  BBMarkers[BB].push_back({Instructions.size(), M});
149  Instructions.push_back(I);
150 
151  if (M.IsStart) {
152  BlockInfo.End.reset(M.AllocaNo);
153  BlockInfo.Begin.set(M.AllocaNo);
154  } else {
155  BlockInfo.Begin.reset(M.AllocaNo);
156  BlockInfo.End.set(M.AllocaNo);
157  }
158  };
159 
160  if (BlockMarkerSet.size() == 1) {
161  ProcessMarker(BlockMarkerSet.begin()->getFirst(),
162  BlockMarkerSet.begin()->getSecond());
163  } else {
164  // Scan the BB to determine the marker order.
165  for (const Instruction &I : *BB) {
166  const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
167  if (!II)
168  continue;
169  auto It = BlockMarkerSet.find(II);
170  if (It == BlockMarkerSet.end())
171  continue;
172  ProcessMarker(II, It->getSecond());
173  }
174  }
175 
176  BlockInstRange[BB] = std::make_pair(BBStart, Instructions.size());
177  }
178 }
179 
180 void StackLifetime::calculateLocalLiveness() {
181  bool Changed = true;
182  while (Changed) {
183  Changed = false;
184 
185  for (const BasicBlock *BB : depth_first(&F)) {
186  BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond();
187 
188  // Compute LiveIn by unioning together the LiveOut sets of all preds.
189  BitVector LocalLiveIn;
190  for (auto *PredBB : predecessors(BB)) {
191  LivenessMap::const_iterator I = BlockLiveness.find(PredBB);
192  // If a predecessor is unreachable, ignore it.
193  if (I == BlockLiveness.end())
194  continue;
195  switch (Type) {
196  case LivenessType::May:
197  LocalLiveIn |= I->second.LiveOut;
198  break;
199  case LivenessType::Must:
200  if (LocalLiveIn.empty())
201  LocalLiveIn = I->second.LiveOut;
202  else
203  LocalLiveIn &= I->second.LiveOut;
204  break;
205  }
206  }
207 
208  // Compute LiveOut by subtracting out lifetimes that end in this
209  // block, then adding in lifetimes that begin in this block. If
210  // we have both BEGIN and END markers in the same basic block
211  // then we know that the BEGIN marker comes after the END,
212  // because we already handle the case where the BEGIN comes
213  // before the END when collecting the markers (and building the
214  // BEGIN/END vectors).
215  BitVector LocalLiveOut = LocalLiveIn;
216  LocalLiveOut.reset(BlockInfo.End);
217  LocalLiveOut |= BlockInfo.Begin;
218 
219  // Update block LiveIn set, noting whether it has changed.
220  if (LocalLiveIn.test(BlockInfo.LiveIn)) {
221  BlockInfo.LiveIn |= LocalLiveIn;
222  }
223 
224  // Update block LiveOut set, noting whether it has changed.
225  if (LocalLiveOut.test(BlockInfo.LiveOut)) {
226  Changed = true;
227  BlockInfo.LiveOut |= LocalLiveOut;
228  }
229  }
230  } // while changed.
231 }
232 
233 void StackLifetime::calculateLiveIntervals() {
234  for (auto IT : BlockLiveness) {
235  const BasicBlock *BB = IT.getFirst();
236  BlockLifetimeInfo &BlockInfo = IT.getSecond();
237  unsigned BBStart, BBEnd;
238  std::tie(BBStart, BBEnd) = BlockInstRange[BB];
239 
240  BitVector Started, Ended;
241  Started.resize(NumAllocas);
242  Ended.resize(NumAllocas);
244  Start.resize(NumAllocas);
245 
246  // LiveIn ranges start at the first instruction.
247  for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) {
248  if (BlockInfo.LiveIn.test(AllocaNo)) {
249  Started.set(AllocaNo);
250  Start[AllocaNo] = BBStart;
251  }
252  }
253 
254  for (auto &It : BBMarkers[BB]) {
255  unsigned InstNo = It.first;
256  bool IsStart = It.second.IsStart;
257  unsigned AllocaNo = It.second.AllocaNo;
258 
259  if (IsStart) {
260  if (!Started.test(AllocaNo)) {
261  Started.set(AllocaNo);
262  Ended.reset(AllocaNo);
263  Start[AllocaNo] = InstNo;
264  }
265  } else {
266  if (Started.test(AllocaNo)) {
267  LiveRanges[AllocaNo].addRange(Start[AllocaNo], InstNo);
268  Started.reset(AllocaNo);
269  }
270  Ended.set(AllocaNo);
271  }
272  }
273 
274  for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo)
275  if (Started.test(AllocaNo))
276  LiveRanges[AllocaNo].addRange(Start[AllocaNo], BBEnd);
277  }
278 }
279 
280 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
281 LLVM_DUMP_METHOD void StackLifetime::dumpAllocas() const {
282  dbgs() << "Allocas:\n";
283  for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo)
284  dbgs() << " " << AllocaNo << ": " << *Allocas[AllocaNo] << "\n";
285 }
286 
287 LLVM_DUMP_METHOD void StackLifetime::dumpBlockLiveness() const {
288  dbgs() << "Block liveness:\n";
289  for (auto IT : BlockLiveness) {
290  const BasicBlock *BB = IT.getFirst();
291  const BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond();
292  auto BlockRange = BlockInstRange.find(BB)->getSecond();
293  dbgs() << " BB (" << BB->getName() << ") [" << BlockRange.first << ", " << BlockRange.second
294  << "): begin " << BlockInfo.Begin << ", end " << BlockInfo.End
295  << ", livein " << BlockInfo.LiveIn << ", liveout "
296  << BlockInfo.LiveOut << "\n";
297  }
298 }
299 
300 LLVM_DUMP_METHOD void StackLifetime::dumpLiveRanges() const {
301  dbgs() << "Alloca liveness:\n";
302  for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo)
303  dbgs() << " " << AllocaNo << ": " << LiveRanges[AllocaNo] << "\n";
304 }
305 #endif
306 
310  : F(F), Type(Type), Allocas(Allocas), NumAllocas(Allocas.size()) {
311  LLVM_DEBUG(dumpAllocas());
312 
313  for (unsigned I = 0; I < NumAllocas; ++I)
314  AllocaNumbering[Allocas[I]] = I;
315 
316  collectMarkers();
317 }
318 
320  if (HasUnknownLifetimeStartOrEnd) {
321  // There is marker which we can't assign to a specific alloca, so we
322  // fallback to the most conservative results for the type.
323  switch (Type) {
324  case LivenessType::May:
325  LiveRanges.resize(NumAllocas, getFullLiveRange());
326  break;
327  case LivenessType::Must:
328  LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
329  break;
330  }
331  return;
332  }
333 
334  LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
335  for (unsigned I = 0; I < NumAllocas; ++I)
336  if (!InterestingAllocas.test(I))
337  LiveRanges[I] = getFullLiveRange();
338 
339  calculateLocalLiveness();
340  LLVM_DEBUG(dumpBlockLiveness());
341  calculateLiveIntervals();
342  LLVM_DEBUG(dumpLiveRanges());
343 }
344 
346  : public AssemblyAnnotationWriter {
347  const StackLifetime &SL;
348 
349  void printInstrAlive(unsigned InstrNo, formatted_raw_ostream &OS) {
351  for (const auto &KV : SL.AllocaNumbering) {
352  if (SL.LiveRanges[KV.getSecond()].test(InstrNo))
353  Names.push_back(KV.getFirst()->getName());
354  }
355  llvm::sort(Names);
356  OS << " ; Alive: <" << llvm::join(Names, " ") << ">\n";
357  }
358 
359  void emitBasicBlockStartAnnot(const BasicBlock *BB,
360  formatted_raw_ostream &OS) override {
361  auto ItBB = SL.BlockInstRange.find(BB);
362  if (ItBB == SL.BlockInstRange.end())
363  return; // Unreachable.
364  printInstrAlive(ItBB->getSecond().first, OS);
365  }
366 
367  void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
368  const Instruction *Instr = dyn_cast<Instruction>(&V);
369  if (!Instr || !SL.isReachable(Instr))
370  return;
371 
373  for (const auto &KV : SL.AllocaNumbering) {
374  if (SL.isAliveAfter(KV.getFirst(), Instr))
375  Names.push_back(KV.getFirst()->getName());
376  }
377  llvm::sort(Names);
378  OS << "\n ; Alive: <" << llvm::join(Names, " ") << ">\n";
379  }
380 
381 public:
383 };
384 
386  LifetimeAnnotationWriter AAW(*this);
387  F.print(OS, &AAW);
388 }
389 
393  for (auto &I : instructions(F))
394  if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I))
395  Allocas.push_back(AI);
396  StackLifetime SL(F, Allocas, Type);
397  SL.run();
398  SL.print(OS);
399  return PreservedAnalyses::all();
400 }
401 
403  raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
405  OS, MapClassName2PassName);
406  OS << "<";
407  switch (Type) {
409  OS << "may";
410  break;
412  OS << "must";
413  break;
414  }
415  OS << ">";
416 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
llvm::predecessors
pred_range predecessors(BasicBlock *BB)
Definition: CFG.h:127
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:506
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::StackLifetime::isAliveAfter
bool isAliveAfter(const AllocaInst *AI, const Instruction *I) const
Returns true if the alloca is alive after the instruction.
Definition: StackLifetime.cpp:50
llvm::upper_bound
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1723
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
IntrinsicInst.h
llvm::PassInfoMixin< StackLifetimePrinterPass >
InstIterator.h
llvm::Function
Definition: Function.h:62
llvm::Function::print
void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW=nullptr, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const
Print the function to an output stream with an optional AssemblyAnnotationWriter.
Definition: AsmWriter.cpp:4464
Pass.h
llvm::BitVector::set
BitVector & set()
Definition: BitVector.h:343
llvm::IntrinsicInst::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:52
llvm::SmallVector< unsigned, 8 >
ValueTracking.h
llvm::StackLifetime::StackLifetime
StackLifetime(const Function &F, ArrayRef< const AllocaInst * > Allocas, LivenessType Type)
Definition: StackLifetime.cpp:307
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::BitVector::resize
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
Definition: BitVector.h:333
llvm::StackLifetime::LivenessType::Must
@ Must
STLExtras.h
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
DepthFirstIterator.h
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::StackLifetime::print
void print(raw_ostream &O)
Definition: StackLifetime.cpp:385
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::DenseMapBase< DenseMap< const BasicBlock *, BlockLifetimeInfo, DenseMapInfo< const BasicBlock * >, llvm::detail::DenseMapPair< const BasicBlock *, BlockLifetimeInfo > >, const BasicBlock *, BlockLifetimeInfo, DenseMapInfo< const BasicBlock * >, llvm::detail::DenseMapPair< const BasicBlock *, BlockLifetimeInfo > >::const_iterator
DenseMapIterator< const BasicBlock *, BlockLifetimeInfo, DenseMapInfo< const BasicBlock * >, llvm::detail::DenseMapPair< const BasicBlock *, BlockLifetimeInfo >, true > const_iterator
Definition: DenseMap.h:72
CommandLine.h
FormattedStream.h
StackLifetime.h
llvm::StackLifetime::isReachable
bool isReachable(const Instruction *I) const
Returns true if instruction is reachable from entry.
Definition: StackLifetime.cpp:46
Intrinsics.h
llvm::Instruction
Definition: Instruction.h:45
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::BitVector
Definition: BitVector.h:74
llvm::Instruction::isLifetimeStartOrEnd
bool isLifetimeStartOrEnd() const
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
Definition: Instruction.cpp:712
llvm::AllocaInst::getAllocationSizeInBits
Optional< TypeSize > getAllocationSizeInBits(const DataLayout &DL) const
Get allocation size in bits.
Definition: Instructions.cpp:57
llvm::BitVector::empty
bool empty() const
empty - Tests whether there are no bits in this bitvector.
Definition: BitVector.h:148
CFG.h
AssemblyAnnotationWriter.h
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:168
llvm::StackLifetime::LivenessType::May
@ May
BasicBlock.h
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:578
llvm::StackLifetime::getLiveRange
const LiveRange & getLiveRange(const AllocaInst *AI) const
Returns a set of "interesting" instructions where the given alloca is live.
Definition: StackLifetime.cpp:40
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:59
StringExtras.h
llvm::StackLifetime
Compute live ranges of allocas.
Definition: StackLifetime.h:38
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
llvm::formatted_raw_ostream
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
Definition: FormattedStream.h:30
llvm::StackLifetime::LivenessType
LivenessType
Definition: StackLifetime.h:84
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LiveRange
SI Optimize VGPR LiveRange
Definition: SIOptimizeVGPRLiveRange.cpp:570
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1581
llvm::StackLifetimePrinterPass::printPipeline
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Definition: StackLifetime.cpp:402
llvm::StackLifetimePrinterPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: StackLifetime.cpp:390
llvm::StackLifetime::run
void run()
Definition: StackLifetime.cpp:319
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
IT
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate IT block based on arch"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT, "arm-no-restrict-it", "Allow IT blocks based on ARMv7")))
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::StackLifetime::LiveRange
This class represents a set of interesting instructions where an alloca is live.
Definition: StackLifetime.h:64
Compiler.h
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::StackLifetime::getFullLiveRange
LiveRange getFullLiveRange() const
Returns a live range that represents an alloca that is live throughout the entire function.
Definition: StackLifetime.h:163
llvm::depth_first
iterator_range< df_iterator< T > > depth_first(const T &G)
Definition: DepthFirstIterator.h:229
llvm::StackLifetime::LifetimeAnnotationWriter
Definition: StackLifetime.cpp:345
llvm::BitVector::test
bool test(unsigned Idx) const
Definition: BitVector.h:447
llvm::DenseMapBase::end
iterator end()
Definition: DenseMap.h:83
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
llvm::AssemblyAnnotationWriter
Definition: AssemblyAnnotationWriter.h:27
Casting.h
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1541
llvm::BitVector::reset
BitVector & reset()
Definition: BitVector.h:384
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:45
llvm::StackLifetime::LifetimeAnnotationWriter::LifetimeAnnotationWriter
LifetimeAnnotationWriter(const StackLifetime &SL)
Definition: StackLifetime.cpp:382
Instructions.h
SmallVector.h
User.h
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1343
llvm::DenseMapBase::try_emplace
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
Definition: DenseMap.h:222
findMatchingAlloca
static const AllocaInst * findMatchingAlloca(const IntrinsicInst &II, const DataLayout &DL)
Definition: StackLifetime.cpp:69
llvm::Module::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:401
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::StackLifetime::LiveRange::test
bool test(unsigned Idx) const
Definition: StackLifetime.h:79
llvm::AllocaInst
an instruction to allocate memory on the stack
Definition: Instructions.h:62
Value.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
Debug.h
llvm::findAllocaForValue
AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
Definition: ValueTracking.cpp:4546