LLVM  13.0.0git
SCCP.cpp
Go to the documentation of this file.
1 //===- SCCP.cpp - Sparse Conditional Constant Propagation -----------------===//
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 //
9 // This file implements sparse conditional constant propagation and merging:
10 //
11 // Specifically, this:
12 // * Assumes values are constant unless proven otherwise
13 // * Assumes BasicBlocks are dead unless proven otherwise
14 // * Proves values to be constant, and replaces them with constants
15 // * Proves conditional branches to be unconditional
16 //
17 //===----------------------------------------------------------------------===//
18 
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/DenseSet.h"
23 #include "llvm/ADT/MapVector.h"
25 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/ADT/SetVector.h"
27 #include "llvm/ADT/SmallPtrSet.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/ADT/Statistic.h"
38 #include "llvm/IR/BasicBlock.h"
39 #include "llvm/IR/Constant.h"
40 #include "llvm/IR/Constants.h"
41 #include "llvm/IR/DataLayout.h"
42 #include "llvm/IR/DerivedTypes.h"
43 #include "llvm/IR/Function.h"
44 #include "llvm/IR/GlobalVariable.h"
45 #include "llvm/IR/InstVisitor.h"
46 #include "llvm/IR/InstrTypes.h"
47 #include "llvm/IR/Instruction.h"
48 #include "llvm/IR/Instructions.h"
49 #include "llvm/IR/Module.h"
50 #include "llvm/IR/PassManager.h"
51 #include "llvm/IR/Type.h"
52 #include "llvm/IR/User.h"
53 #include "llvm/IR/Value.h"
54 #include "llvm/InitializePasses.h"
55 #include "llvm/Pass.h"
56 #include "llvm/Support/Casting.h"
57 #include "llvm/Support/Debug.h"
60 #include "llvm/Transforms/Scalar.h"
63 #include <cassert>
64 #include <utility>
65 #include <vector>
66 
67 using namespace llvm;
68 
69 #define DEBUG_TYPE "sccp"
70 
71 STATISTIC(NumInstRemoved, "Number of instructions removed");
72 STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
73 STATISTIC(NumInstReplaced,
74  "Number of instructions replaced with (simpler) instruction");
75 
76 STATISTIC(IPNumInstRemoved, "Number of instructions removed by IPSCCP");
77 STATISTIC(IPNumArgsElimed ,"Number of arguments constant propagated by IPSCCP");
78 STATISTIC(IPNumGlobalConst, "Number of globals found to be constant by IPSCCP");
79 STATISTIC(
80  IPNumInstReplaced,
81  "Number of instructions replaced with (simpler) instruction by IPSCCP");
82 
83 // Helper to check if \p LV is either a constant or a constant
84 // range with a single element. This should cover exactly the same cases as the
85 // old ValueLatticeElement::isConstant() and is intended to be used in the
86 // transition to ValueLatticeElement.
87 static bool isConstant(const ValueLatticeElement &LV) {
88  return LV.isConstant() ||
90 }
91 
92 // Helper to check if \p LV is either overdefined or a constant range with more
93 // than a single element. This should cover exactly the same cases as the old
94 // ValueLatticeElement::isOverdefined() and is intended to be used in the
95 // transition to ValueLatticeElement.
96 static bool isOverdefined(const ValueLatticeElement &LV) {
97  return !LV.isUnknownOrUndef() && !isConstant(LV);
98 }
99 
100 
101 
102 
103 static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) {
104  Constant *Const = nullptr;
105  if (V->getType()->isStructTy()) {
106  std::vector<ValueLatticeElement> IVs = Solver.getStructLatticeValueFor(V);
107  if (any_of(IVs,
108  [](const ValueLatticeElement &LV) { return isOverdefined(LV); }))
109  return false;
110  std::vector<Constant *> ConstVals;
111  auto *ST = cast<StructType>(V->getType());
112  for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
113  ValueLatticeElement V = IVs[i];
114  ConstVals.push_back(isConstant(V)
115  ? Solver.getConstant(V)
116  : UndefValue::get(ST->getElementType(i)));
117  }
118  Const = ConstantStruct::get(ST, ConstVals);
119  } else {
120  const ValueLatticeElement &IV = Solver.getLatticeValueFor(V);
121  if (isOverdefined(IV))
122  return false;
123 
124  Const =
125  isConstant(IV) ? Solver.getConstant(IV) : UndefValue::get(V->getType());
126  }
127  assert(Const && "Constant is nullptr here!");
128 
129  // Replacing `musttail` instructions with constant breaks `musttail` invariant
130  // unless the call itself can be removed.
131  // Calls with "clang.arc.attachedcall" implicitly use the return value and
132  // those uses cannot be updated with a constant.
133  CallBase *CB = dyn_cast<CallBase>(V);
134  if (CB && ((CB->isMustTailCall() && !CB->isSafeToRemove()) ||
136  Function *F = CB->getCalledFunction();
137 
138  // Don't zap returns of the callee
139  if (F)
141 
142  LLVM_DEBUG(dbgs() << " Can\'t treat the result of call " << *CB
143  << " as a constant\n");
144  return false;
145  }
146 
147  LLVM_DEBUG(dbgs() << " Constant: " << *Const << " = " << *V << '\n');
148 
149  // Replaces all of the uses of a variable with uses of the constant.
150  V->replaceAllUsesWith(Const);
151  return true;
152 }
153 
155  SmallPtrSetImpl<Value *> &InsertedValues,
156  Statistic &InstRemovedStat,
157  Statistic &InstReplacedStat) {
158  bool MadeChanges = false;
159  for (Instruction &Inst : make_early_inc_range(BB)) {
160  if (Inst.getType()->isVoidTy())
161  continue;
162  if (tryToReplaceWithConstant(Solver, &Inst)) {
163  if (Inst.isSafeToRemove())
164  Inst.eraseFromParent();
165  // Hey, we just changed something!
166  MadeChanges = true;
167  ++InstRemovedStat;
168  } else if (isa<SExtInst>(&Inst)) {
169  Value *ExtOp = Inst.getOperand(0);
170  if (isa<Constant>(ExtOp) || InsertedValues.count(ExtOp))
171  continue;
172  const ValueLatticeElement &IV = Solver.getLatticeValueFor(ExtOp);
173  if (!IV.isConstantRange(/*UndefAllowed=*/false))
174  continue;
175  if (IV.getConstantRange().isAllNonNegative()) {
176  auto *ZExt = new ZExtInst(ExtOp, Inst.getType(), "", &Inst);
177  InsertedValues.insert(ZExt);
178  Inst.replaceAllUsesWith(ZExt);
179  Solver.removeLatticeValueFor(&Inst);
180  Inst.eraseFromParent();
181  InstReplacedStat++;
182  MadeChanges = true;
183  }
184  }
185  }
186  return MadeChanges;
187 }
188 
189 // runSCCP() - Run the Sparse Conditional Constant Propagation algorithm,
190 // and return true if the function was modified.
191 static bool runSCCP(Function &F, const DataLayout &DL,
192  const TargetLibraryInfo *TLI) {
193  LLVM_DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n");
194  SCCPSolver Solver(
195  DL, [TLI](Function &F) -> const TargetLibraryInfo & { return *TLI; },
196  F.getContext());
197 
198  // Mark the first block of the function as being executable.
199  Solver.markBlockExecutable(&F.front());
200 
201  // Mark all arguments to the function as being overdefined.
202  for (Argument &AI : F.args())
203  Solver.markOverdefined(&AI);
204 
205  // Solve for constants.
206  bool ResolvedUndefs = true;
207  while (ResolvedUndefs) {
208  Solver.solve();
209  LLVM_DEBUG(dbgs() << "RESOLVING UNDEFs\n");
210  ResolvedUndefs = Solver.resolvedUndefsIn(F);
211  }
212 
213  bool MadeChanges = false;
214 
215  // If we decided that there are basic blocks that are dead in this function,
216  // delete their contents now. Note that we cannot actually delete the blocks,
217  // as we cannot modify the CFG of the function.
218 
219  SmallPtrSet<Value *, 32> InsertedValues;
220  for (BasicBlock &BB : F) {
221  if (!Solver.isBlockExecutable(&BB)) {
222  LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << BB);
223 
224  ++NumDeadBlocks;
225  NumInstRemoved += removeAllNonTerminatorAndEHPadInstructions(&BB).first;
226 
227  MadeChanges = true;
228  continue;
229  }
230 
231  MadeChanges |= simplifyInstsInBlock(Solver, BB, InsertedValues,
232  NumInstRemoved, NumInstReplaced);
233  }
234 
235  return MadeChanges;
236 }
237 
239  const DataLayout &DL = F.getParent()->getDataLayout();
240  auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
241  if (!runSCCP(F, DL, &TLI))
242  return PreservedAnalyses::all();
243 
244  auto PA = PreservedAnalyses();
245  PA.preserve<GlobalsAA>();
246  PA.preserveSet<CFGAnalyses>();
247  return PA;
248 }
249 
250 namespace {
251 
252 //===--------------------------------------------------------------------===//
253 //
254 /// SCCP Class - This class uses the SCCPSolver to implement a per-function
255 /// Sparse Conditional Constant Propagator.
256 ///
257 class SCCPLegacyPass : public FunctionPass {
258 public:
259  // Pass identification, replacement for typeid
260  static char ID;
261 
262  SCCPLegacyPass() : FunctionPass(ID) {
264  }
265 
266  void getAnalysisUsage(AnalysisUsage &AU) const override {
269  AU.setPreservesCFG();
270  }
271 
272  // runOnFunction - Run the Sparse Conditional Constant Propagation
273  // algorithm, and return true if the function was modified.
274  bool runOnFunction(Function &F) override {
275  if (skipFunction(F))
276  return false;
277  const DataLayout &DL = F.getParent()->getDataLayout();
278  const TargetLibraryInfo *TLI =
279  &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
280  return runSCCP(F, DL, TLI);
281  }
282 };
283 
284 } // end anonymous namespace
285 
286 char SCCPLegacyPass::ID = 0;
287 
288 INITIALIZE_PASS_BEGIN(SCCPLegacyPass, "sccp",
289  "Sparse Conditional Constant Propagation", false, false)
291 INITIALIZE_PASS_END(SCCPLegacyPass, "sccp",
292  "Sparse Conditional Constant Propagation", false, false)
293 
294 // createSCCPPass - This is the public interface to this file.
295 FunctionPass *llvm::createSCCPPass() { return new SCCPLegacyPass(); }
296 
298  SmallVector<ReturnInst *, 8> &ReturnsToZap,
299  SCCPSolver &Solver) {
300  // We can only do this if we know that nothing else can call the function.
301  if (!Solver.isArgumentTrackedFunction(&F))
302  return;
303 
304  if (Solver.mustPreserveReturn(&F)) {
305  LLVM_DEBUG(
306  dbgs()
307  << "Can't zap returns of the function : " << F.getName()
308  << " due to present musttail or \"clang.arc.attachedcall\" call of "
309  "it\n");
310  return;
311  }
312 
313  assert(
314  all_of(F.users(),
315  [&Solver](User *U) {
316  if (isa<Instruction>(U) &&
317  !Solver.isBlockExecutable(cast<Instruction>(U)->getParent()))
318  return true;
319  // Non-callsite uses are not impacted by zapping. Also, constant
320  // uses (like blockaddresses) could stuck around, without being
321  // used in the underlying IR, meaning we do not have lattice
322  // values for them.
323  if (!isa<CallBase>(U))
324  return true;
325  if (U->getType()->isStructTy()) {
326  return all_of(Solver.getStructLatticeValueFor(U),
327  [](const ValueLatticeElement &LV) {
328  return !isOverdefined(LV);
329  });
330  }
331  return !isOverdefined(Solver.getLatticeValueFor(U));
332  }) &&
333  "We can only zap functions where all live users have a concrete value");
334 
335  for (BasicBlock &BB : F) {
336  if (CallInst *CI = BB.getTerminatingMustTailCall()) {
337  LLVM_DEBUG(dbgs() << "Can't zap return of the block due to present "
338  << "musttail call : " << *CI << "\n");
339  (void)CI;
340  return;
341  }
342 
343  if (auto *RI = dyn_cast<ReturnInst>(BB.getTerminator()))
344  if (!isa<UndefValue>(RI->getOperand(0)))
345  ReturnsToZap.push_back(RI);
346  }
347 }
348 
349 static bool removeNonFeasibleEdges(const SCCPSolver &Solver, BasicBlock *BB,
350  DomTreeUpdater &DTU) {
351  SmallPtrSet<BasicBlock *, 8> FeasibleSuccessors;
352  bool HasNonFeasibleEdges = false;
353  for (BasicBlock *Succ : successors(BB)) {
354  if (Solver.isEdgeFeasible(BB, Succ))
355  FeasibleSuccessors.insert(Succ);
356  else
357  HasNonFeasibleEdges = true;
358  }
359 
360  // All edges feasible, nothing to do.
361  if (!HasNonFeasibleEdges)
362  return false;
363 
364  // SCCP can only determine non-feasible edges for br, switch and indirectbr.
365  Instruction *TI = BB->getTerminator();
366  assert((isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
367  isa<IndirectBrInst>(TI)) &&
368  "Terminator must be a br, switch or indirectbr");
369 
370  if (FeasibleSuccessors.size() == 1) {
371  // Replace with an unconditional branch to the only feasible successor.
372  BasicBlock *OnlyFeasibleSuccessor = *FeasibleSuccessors.begin();
374  bool HaveSeenOnlyFeasibleSuccessor = false;
375  for (BasicBlock *Succ : successors(BB)) {
376  if (Succ == OnlyFeasibleSuccessor && !HaveSeenOnlyFeasibleSuccessor) {
377  // Don't remove the edge to the only feasible successor the first time
378  // we see it. We still do need to remove any multi-edges to it though.
379  HaveSeenOnlyFeasibleSuccessor = true;
380  continue;
381  }
382 
383  Succ->removePredecessor(BB);
384  Updates.push_back({DominatorTree::Delete, BB, Succ});
385  }
386 
387  BranchInst::Create(OnlyFeasibleSuccessor, BB);
388  TI->eraseFromParent();
389  DTU.applyUpdatesPermissive(Updates);
390  } else if (FeasibleSuccessors.size() > 1) {
391  SwitchInstProfUpdateWrapper SI(*cast<SwitchInst>(TI));
393  for (auto CI = SI->case_begin(); CI != SI->case_end();) {
394  if (FeasibleSuccessors.contains(CI->getCaseSuccessor())) {
395  ++CI;
396  continue;
397  }
398 
399  BasicBlock *Succ = CI->getCaseSuccessor();
400  Succ->removePredecessor(BB);
401  Updates.push_back({DominatorTree::Delete, BB, Succ});
402  SI.removeCase(CI);
403  // Don't increment CI, as we removed a case.
404  }
405 
406  DTU.applyUpdatesPermissive(Updates);
407  } else {
408  llvm_unreachable("Must have at least one feasible successor");
409  }
410  return true;
411 }
412 
414  Module &M, const DataLayout &DL,
415  std::function<const TargetLibraryInfo &(Function &)> GetTLI,
416  function_ref<AnalysisResultsForFn(Function &)> getAnalysis) {
417  SCCPSolver Solver(DL, GetTLI, M.getContext());
418 
419  // Loop over all functions, marking arguments to those with their addresses
420  // taken or that are external as overdefined.
421  for (Function &F : M) {
422  if (F.isDeclaration())
423  continue;
424 
425  Solver.addAnalysis(F, getAnalysis(F));
426 
427  // Determine if we can track the function's return values. If so, add the
428  // function to the solver's set of return-tracked functions.
430  Solver.addTrackedFunction(&F);
431 
432  // Determine if we can track the function's arguments. If so, add the
433  // function to the solver's set of argument-tracked functions.
435  Solver.addArgumentTrackedFunction(&F);
436  continue;
437  }
438 
439  // Assume the function is called.
440  Solver.markBlockExecutable(&F.front());
441 
442  // Assume nothing about the incoming arguments.
443  for (Argument &AI : F.args())
444  Solver.markOverdefined(&AI);
445  }
446 
447  // Determine if we can track any of the module's global variables. If so, add
448  // the global variables we can track to the solver's set of tracked global
449  // variables.
450  for (GlobalVariable &G : M.globals()) {
451  G.removeDeadConstantUsers();
453  Solver.trackValueOfGlobalVariable(&G);
454  }
455 
456  // Solve for constants.
457  bool ResolvedUndefs = true;
458  Solver.solve();
459  while (ResolvedUndefs) {
460  LLVM_DEBUG(dbgs() << "RESOLVING UNDEFS\n");
461  ResolvedUndefs = false;
462  for (Function &F : M) {
463  if (Solver.resolvedUndefsIn(F))
464  ResolvedUndefs = true;
465  }
466  if (ResolvedUndefs)
467  Solver.solve();
468  }
469 
470  bool MadeChanges = false;
471 
472  // Iterate over all of the instructions in the module, replacing them with
473  // constants if we have found them to be of constant values.
474 
475  for (Function &F : M) {
476  if (F.isDeclaration())
477  continue;
478 
479  SmallVector<BasicBlock *, 512> BlocksToErase;
480 
481  if (Solver.isBlockExecutable(&F.front())) {
482  bool ReplacedPointerArg = false;
483  for (Argument &Arg : F.args()) {
484  if (!Arg.use_empty() && tryToReplaceWithConstant(Solver, &Arg)) {
485  ReplacedPointerArg |= Arg.getType()->isPointerTy();
486  ++IPNumArgsElimed;
487  }
488  }
489 
490  // If we replaced an argument, the argmemonly and
491  // inaccessiblemem_or_argmemonly attributes do not hold any longer. Remove
492  // them from both the function and callsites.
493  if (ReplacedPointerArg) {
494  AttrBuilder AttributesToRemove;
495  AttributesToRemove.addAttribute(Attribute::ArgMemOnly);
496  AttributesToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly);
497  F.removeAttributes(AttributeList::FunctionIndex, AttributesToRemove);
498 
499  for (User *U : F.users()) {
500  auto *CB = dyn_cast<CallBase>(U);
501  if (!CB || CB->getCalledFunction() != &F)
502  continue;
503 
504  CB->removeAttributes(AttributeList::FunctionIndex,
505  AttributesToRemove);
506  }
507  }
508  }
509 
510  SmallPtrSet<Value *, 32> InsertedValues;
511  for (BasicBlock &BB : F) {
512  if (!Solver.isBlockExecutable(&BB)) {
513  LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << BB);
514  ++NumDeadBlocks;
515 
516  MadeChanges = true;
517 
518  if (&BB != &F.front())
519  BlocksToErase.push_back(&BB);
520  continue;
521  }
522 
523  MadeChanges |= simplifyInstsInBlock(Solver, BB, InsertedValues,
524  IPNumInstRemoved, IPNumInstReplaced);
525  }
526 
527  DomTreeUpdater DTU = Solver.getDTU(F);
528  // Change dead blocks to unreachable. We do it after replacing constants
529  // in all executable blocks, because changeToUnreachable may remove PHI
530  // nodes in executable blocks we found values for. The function's entry
531  // block is not part of BlocksToErase, so we have to handle it separately.
532  for (BasicBlock *BB : BlocksToErase) {
533  NumInstRemoved +=
534  changeToUnreachable(BB->getFirstNonPHI(), /*UseLLVMTrap=*/false,
535  /*PreserveLCSSA=*/false, &DTU);
536  }
537  if (!Solver.isBlockExecutable(&F.front()))
538  NumInstRemoved += changeToUnreachable(F.front().getFirstNonPHI(),
539  /*UseLLVMTrap=*/false,
540  /*PreserveLCSSA=*/false, &DTU);
541 
542  for (BasicBlock &BB : F)
543  MadeChanges |= removeNonFeasibleEdges(Solver, &BB, DTU);
544 
545  for (BasicBlock *DeadBB : BlocksToErase)
546  DTU.deleteBB(DeadBB);
547 
548  for (BasicBlock &BB : F) {
549  for (BasicBlock::iterator BI = BB.begin(), E = BB.end(); BI != E;) {
550  Instruction *Inst = &*BI++;
551  if (Solver.getPredicateInfoFor(Inst)) {
552  if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
553  if (II->getIntrinsicID() == Intrinsic::ssa_copy) {
554  Value *Op = II->getOperand(0);
555  Inst->replaceAllUsesWith(Op);
556  Inst->eraseFromParent();
557  }
558  }
559  }
560  }
561  }
562  }
563 
564  // If we inferred constant or undef return values for a function, we replaced
565  // all call uses with the inferred value. This means we don't need to bother
566  // actually returning anything from the function. Replace all return
567  // instructions with return undef.
568  //
569  // Do this in two stages: first identify the functions we should process, then
570  // actually zap their returns. This is important because we can only do this
571  // if the address of the function isn't taken. In cases where a return is the
572  // last use of a function, the order of processing functions would affect
573  // whether other functions are optimizable.
574  SmallVector<ReturnInst*, 8> ReturnsToZap;
575 
576  for (const auto &I : Solver.getTrackedRetVals()) {
577  Function *F = I.first;
578  const ValueLatticeElement &ReturnValue = I.second;
579 
580  // If there is a known constant range for the return value, add !range
581  // metadata to the function's call sites.
582  if (ReturnValue.isConstantRange() &&
583  !ReturnValue.getConstantRange().isSingleElement()) {
584  // Do not add range metadata if the return value may include undef.
585  if (ReturnValue.isConstantRangeIncludingUndef())
586  continue;
587 
588  auto &CR = ReturnValue.getConstantRange();
589  for (User *User : F->users()) {
590  auto *CB = dyn_cast<CallBase>(User);
591  if (!CB || CB->getCalledFunction() != F)
592  continue;
593 
594  // Limit to cases where the return value is guaranteed to be neither
595  // poison nor undef. Poison will be outside any range and currently
596  // values outside of the specified range cause immediate undefined
597  // behavior.
598  if (!isGuaranteedNotToBeUndefOrPoison(CB, nullptr, CB))
599  continue;
600 
601  // Do not touch existing metadata for now.
602  // TODO: We should be able to take the intersection of the existing
603  // metadata and the inferred range.
604  if (CB->getMetadata(LLVMContext::MD_range))
605  continue;
606 
607  LLVMContext &Context = CB->getParent()->getContext();
608  Metadata *RangeMD[] = {
611  CB->setMetadata(LLVMContext::MD_range, MDNode::get(Context, RangeMD));
612  }
613  continue;
614  }
615  if (F->getReturnType()->isVoidTy())
616  continue;
617  if (isConstant(ReturnValue) || ReturnValue.isUnknownOrUndef())
618  findReturnsToZap(*F, ReturnsToZap, Solver);
619  }
620 
621  for (auto F : Solver.getMRVFunctionsTracked()) {
622  assert(F->getReturnType()->isStructTy() &&
623  "The return type should be a struct");
624  StructType *STy = cast<StructType>(F->getReturnType());
625  if (Solver.isStructLatticeConstant(F, STy))
626  findReturnsToZap(*F, ReturnsToZap, Solver);
627  }
628 
629  // Zap all returns which we've identified as zap to change.
630  SmallSetVector<Function *, 8> FuncZappedReturn;
631  for (unsigned i = 0, e = ReturnsToZap.size(); i != e; ++i) {
632  Function *F = ReturnsToZap[i]->getParent()->getParent();
633  ReturnsToZap[i]->setOperand(0, UndefValue::get(F->getReturnType()));
634  // Record all functions that are zapped.
635  FuncZappedReturn.insert(F);
636  }
637 
638  // Remove the returned attribute for zapped functions and the
639  // corresponding call sites.
640  for (Function *F : FuncZappedReturn) {
641  for (Argument &A : F->args())
642  F->removeParamAttr(A.getArgNo(), Attribute::Returned);
643  for (Use &U : F->uses()) {
644  // Skip over blockaddr users.
645  if (isa<BlockAddress>(U.getUser()))
646  continue;
647  CallBase *CB = cast<CallBase>(U.getUser());
648  for (Use &Arg : CB->args())
649  CB->removeParamAttr(CB->getArgOperandNo(&Arg), Attribute::Returned);
650  }
651  }
652 
653  // If we inferred constant or undef values for globals variables, we can
654  // delete the global and any stores that remain to it.
655  for (auto &I : make_early_inc_range(Solver.getTrackedGlobals())) {
656  GlobalVariable *GV = I.first;
657  if (isOverdefined(I.second))
658  continue;
659  LLVM_DEBUG(dbgs() << "Found that GV '" << GV->getName()
660  << "' is constant!\n");
661  while (!GV->use_empty()) {
662  StoreInst *SI = cast<StoreInst>(GV->user_back());
663  SI->eraseFromParent();
664  MadeChanges = true;
665  }
666  M.getGlobalList().erase(GV);
667  ++IPNumGlobalConst;
668  }
669 
670  return MadeChanges;
671 }
i
i
Definition: README.txt:29
llvm::GlobalsAA
Analysis pass providing a never-invalidated alias analysis result.
Definition: GlobalsModRef.h:132
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:29
llvm::ValueLatticeElement::getConstantRange
const ConstantRange & getConstantRange(bool UndefAllowed=true) const
Returns the constant range for this value.
Definition: ValueLattice.h:270
llvm::ValueLatticeElement::isConstant
bool isConstant() const
Definition: ValueLattice.h:241
llvm
Definition: AllocatorList.h:23
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::DomTreeUpdater::deleteBB
void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Definition: DomTreeUpdater.cpp:177
llvm::CallBase::getOperandBundle
Optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Definition: InstrTypes.h:1982
sccp
sccp
Definition: SCCP.cpp:291
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:112
PredicateInfo.h
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:90
llvm::SwitchInstProfUpdateWrapper
A wrapper class to simplify modification of SwitchInst cases along with their prof branch_weights met...
Definition: Instructions.h:3495
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:785
Scalar.h
llvm::AnalysisResultsForFn
Helper struct for bundling up the analysis results per function for IPSCCP.
Definition: SCCPSolver.h:31
llvm::Function
Definition: Function.h:61
llvm::ConstantStruct::get
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1312
Pass.h
isConstant
static bool isConstant(const ValueLatticeElement &LV)
Definition: SCCP.cpp:87
llvm::SCCPSolver::getStructLatticeValueFor
std::vector< ValueLatticeElement > getStructLatticeValueFor(Value *V) const
Definition: SCCPSolver.cpp:1632
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
Statistic.h
ErrorHandling.h
SCCP.h
llvm::initializeSCCPLegacyPassPass
void initializeSCCPLegacyPassPass(PassRegistry &)
MapVector.h
DomTreeUpdater.h
llvm::GlobalVariable
Definition: GlobalVariable.h:40
llvm::ConstantRange::isAllNonNegative
bool isAllNonNegative() const
Return true if all values in this range are non-negative.
Definition: ConstantRange.cpp:365
ValueTracking.h
Local.h
GlobalsModRef.h
llvm::SCCPSolver::getConstant
Constant * getConstant(const ValueLatticeElement &LV) const
Helper to return a Constant if LV is either a constant or a constant range with a single element.
Definition: SCCPSolver.cpp:1664
DenseMap.h
Module.h
llvm::CallBase::isMustTailCall
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Definition: Instructions.cpp:294
llvm::SmallPtrSet
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:449
isGuaranteedNotToBeUndefOrPoison
static bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC, const Instruction *CtxI, const DominatorTree *DT, unsigned Depth, bool PoisonOnly)
Definition: ValueTracking.cpp:5020
llvm::SCCPSolver::markBlockExecutable
bool markBlockExecutable(BasicBlock *BB)
markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
Definition: SCCPSolver.cpp:1583
STLExtras.h
llvm::successors
succ_range successors(Instruction *I)
Definition: CFG.h:262
ConstantFolding.h
INITIALIZE_PASS_END
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Definition: RegBankSelect.cpp:69
llvm::SCCPSolver::addArgumentTrackedFunction
void addArgumentTrackedFunction(Function *F)
Definition: SCCPSolver.cpp:1609
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
PointerIntPair.h
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:205
Instruction.h
llvm::CallBase::removeParamAttr
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Removes the attribute from the given argument.
Definition: InstrTypes.h:1543
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1505
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::ValueLatticeElement::isUnknownOrUndef
bool isUnknownOrUndef() const
Definition: ValueLattice.h:240
Constants.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::SCCPSolver::markOverdefined
void markOverdefined(Value *V)
markOverdefined - Mark the specified value overdefined.
Definition: SCCPSolver.cpp:1658
llvm::User
Definition: User.h:44
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(IPSCCPLegacyPass, "ipsccp", "Interprocedural Sparse Conditional Constant Propagation", false, false) INITIALIZE_PASS_END(IPSCCPLegacyPass
runSCCP
static bool runSCCP(Function &F, const DataLayout &DL, const TargetLibraryInfo *TLI)
Definition: SCCP.cpp:191
InstrTypes.h
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1396
llvm::SCCPSolver::isArgumentTrackedFunction
bool isArgumentTrackedFunction(Function *F)
Returns true if the given function is in the solver's set of argument-tracked functions.
Definition: SCCPSolver.cpp:1613
llvm::ValueLatticeElement::isConstantRangeIncludingUndef
bool isConstantRangeIncludingUndef() const
Definition: ValueLattice.h:243
llvm::ConstantRange::isSingleElement
bool isSingleElement() const
Return true if this set contains exactly one member.
Definition: ConstantRange.h:234
SI
@ SI
Definition: SIInstrInfo.cpp:7342
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
Propagation
Interprocedural Sparse Conditional Constant Propagation
Definition: SCCP.cpp:101
TargetLibraryInfo.h
DenseSet.h
false
Definition: StackSlotColoring.cpp:142
llvm::removeAllNonTerminatorAndEHPadInstructions
std::pair< unsigned, unsigned > removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB)
Remove all instructions from a basic block other than its terminator and any present EH pad instructi...
Definition: Local.cpp:2020
llvm::SCCPSolver::addAnalysis
void addAnalysis(Function &F, AnalysisResultsForFn A)
Definition: SCCPSolver.cpp:1579
llvm::Instruction
Definition: Instruction.h:45
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1770
llvm::DomTreeUpdater
Definition: DomTreeUpdater.h:28
tryToReplaceWithConstant
static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V)
Definition: SCCP.cpp:103
llvm::SCCPSolver::isStructLatticeConstant
bool isStructLatticeConstant(Function *F, StructType *STy)
Definition: SCCPSolver.cpp:1660
SmallPtrSet.h
llvm::Instruction::isSafeToRemove
bool isSafeToRemove() const
Return true if the instruction can be removed if the result is unused.
Definition: Instruction.cpp:662
llvm::Metadata
Root of the metadata hierarchy.
Definition: Metadata.h:62
llvm::canTrackGlobalVariableInterprocedurally
bool canTrackGlobalVariableInterprocedurally(GlobalVariable *GV)
Determine if the value maintained in the given global variable can be tracked interprocedurally.
Definition: ValueLatticeUtils.cpp:27
llvm::LLVMContext::OB_clang_arc_attachedcall
@ OB_clang_arc_attachedcall
Definition: LLVMContext.h:96
llvm::Value::use_empty
bool use_empty() const
Definition: Value.h:357
Type.h
llvm::runIPSCCP
bool runIPSCCP(Module &M, const DataLayout &DL, std::function< const TargetLibraryInfo &(Function &)> GetTLI, function_ref< AnalysisResultsForFn(Function &)> getAnalysis)
Definition: SCCP.cpp:413
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:176
llvm::Value::user_back
User * user_back()
Definition: Value.h:420
llvm::SCCPSolver::getTrackedRetVals
const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals()
getTrackedRetVals - Get the inferred return value map.
Definition: SCCPSolver.cpp:1645
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
BasicBlock.h
llvm::SCCPSolver::getLatticeValueFor
const ValueLatticeElement & getLatticeValueFor(Value *V) const
Definition: SCCPSolver.cpp:1640
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:303
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::Instruction::eraseFromParent
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:78
simplifyInstsInBlock
static bool simplifyInstsInBlock(SCCPSolver &Solver, BasicBlock &BB, SmallPtrSetImpl< Value * > &InsertedValues, Statistic &InstRemovedStat, Statistic &InstReplacedStat)
Definition: SCCP.cpp:154
llvm::TargetLibraryInfoWrapperPass
Definition: TargetLibraryInfo.h:446
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::changeToUnreachable
unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
Definition: Local.cpp:2044
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::SCCPSolver::getPredicateInfoFor
const PredicateBase * getPredicateInfoFor(Instruction *I)
Definition: SCCPSolver.cpp:1587
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::SCCPPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: SCCP.cpp:238
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::AttrBuilder
Definition: Attributes.h:804
llvm::make_early_inc_range
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:581
llvm::SCCPSolver
SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...
Definition: SCCPSolver.h:44
llvm::SmallPtrSetImpl::begin
iterator begin() const
Definition: SmallPtrSet.h:402
ArrayRef.h
llvm::SCCPSolver::getTrackedGlobals
const DenseMap< GlobalVariable *, ValueLatticeElement > & getTrackedGlobals()
getTrackedGlobals - Get and return the set of inferred initializers for global variables.
Definition: SCCPSolver.cpp:1650
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::SmallPtrSetImpl::count
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:382
llvm::ZExtInst
This class represents zero extension of integer types.
Definition: Instructions.h:4730
llvm::createSCCPPass
FunctionPass * createSCCPPass()
Definition: SCCP.cpp:295
llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::insert
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:141
llvm::SCCPSolver::getDTU
DomTreeUpdater getDTU(Function &F)
Definition: SCCPSolver.cpp:1591
isOverdefined
static bool isOverdefined(const ValueLatticeElement &LV)
Definition: SCCP.cpp:96
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1512
DataLayout.h
llvm::StructType
Class to represent struct types.
Definition: DerivedTypes.h:212
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
InstVisitor.h
findReturnsToZap
static void findReturnsToZap(Function &F, SmallVector< ReturnInst *, 8 > &ReturnsToZap, SCCPSolver &Solver)
Definition: SCCP.cpp:297
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
llvm::CFGAnalyses
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:116
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:526
A
* A
Definition: README_ALTIVEC.txt:89
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::SCCPSolver::removeLatticeValueFor
void removeLatticeValueFor(Value *V)
Definition: SCCPSolver.cpp:1636
llvm::ValueLatticeElement
This class represents lattice values for constants.
Definition: ValueLattice.h:27
llvm::SCCPSolver::mustPreserveReturn
bool mustPreserveReturn(Function *F)
Returns true if the return of the given function cannot be modified.
Definition: SCCPSolver.cpp:1605
llvm::TrackingStatistic
Definition: Statistic.h:63
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:298
ValueLatticeUtils.h
llvm::SCCPSolver::isBlockExecutable
bool isBlockExecutable(BasicBlock *BB) const
Definition: SCCPSolver.cpp:1623
llvm::SmallPtrSetImplBase::size
size_type size() const
Definition: SmallPtrSet.h:92
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::SCCPSolver::isEdgeFeasible
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const
Definition: SCCPSolver.cpp:1627
Constant.h
removeNonFeasibleEdges
static bool removeNonFeasibleEdges(const SCCPSolver &Solver, BasicBlock *BB, DomTreeUpdater &DTU)
Definition: SCCP.cpp:349
get
Should compile to something r4 addze r3 instead we get
Definition: README.txt:24
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
GlobalVariable.h
Casting.h
Function.h
PassManager.h
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition: TargetLibraryInfo.h:207
llvm::SCCPSolver::resolvedUndefsIn
bool resolvedUndefsIn(Function &F)
resolvedUndefsIn - While solving the dataflow for a function, we assume that branches on undef values...
Definition: SCCPSolver.cpp:1619
llvm::CallBase::getArgOperandNo
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
Definition: InstrTypes.h:1372
llvm::AttrBuilder::addAttribute
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
Definition: Attributes.h:832
llvm::SCCPSolver::addToMustPreserveReturnsInFunctions
void addToMustPreserveReturnsInFunctions(Function *F)
Add function to the list of functions whose return cannot be modified.
Definition: SCCPSolver.cpp:1601
Instructions.h
llvm::Type::isStructTy
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:223
SmallVector.h
User.h
llvm::canTrackArgumentsInterprocedurally
bool canTrackArgumentsInterprocedurally(Function *F)
Determine if the values of the given function's arguments can be tracked interprocedurally.
Definition: ValueLatticeUtils.cpp:19
llvm::ValueLatticeElement::isConstantRange
bool isConstantRange(bool UndefAllowed=true) const
Returns true if this value is a constant range.
Definition: ValueLattice.h:250
InstructionSimplify.h
llvm::GlobalsAAWrapperPass
Legacy wrapper pass to provide the GlobalsAAResult object.
Definition: GlobalsModRef.h:143
llvm::BasicBlock::removePredecessor
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
Definition: BasicBlock.cpp:321
llvm::SCCPSolver::trackValueOfGlobalVariable
void trackValueOfGlobalVariable(GlobalVariable *GV)
trackValueOfGlobalVariable - Clients can use this method to inform the SCCPSolver that it should trac...
Definition: SCCPSolver.cpp:1593
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1164
DerivedTypes.h
llvm::SmallPtrSetImpl< Value * >
llvm::SmallSetVector
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:307
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1450
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::SCCPSolver::solve
void solve()
Solve - Solve for constants and executable blocks.
Definition: SCCPSolver.cpp:1617
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
raw_ostream.h
llvm::SCCPSolver::addTrackedFunction
void addTrackedFunction(Function *F)
addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...
Definition: SCCPSolver.cpp:1597
llvm::SmallPtrSetImpl::contains
bool contains(ConstPtrType Ptr) const
Definition: SmallPtrSet.h:388
Value.h
InitializePasses.h
ValueLattice.h
llvm::DomTreeUpdater::applyUpdatesPermissive
void applyUpdatesPermissive(ArrayRef< DominatorTree::UpdateType > Updates)
Submit updates to all available trees.
Definition: DomTreeUpdater.cpp:249
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
Debug.h
llvm::TargetLibraryAnalysis
Analysis pass providing the TargetLibraryInfo.
Definition: TargetLibraryInfo.h:421
llvm::SCCPSolver::getMRVFunctionsTracked
const SmallPtrSet< Function *, 16 > getMRVFunctionsTracked()
getMRVFunctionsTracked - Get the set of functions which return multiple values tracked by the pass.
Definition: SCCPSolver.cpp:1654
llvm::CallBase::args
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1322
SetVector.h
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
llvm::SmallPtrSetImpl::insert
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:364
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
llvm::canTrackReturnsInterprocedurally
bool canTrackReturnsInterprocedurally(Function *F)
Determine if the values of the given function's returns can be tracked interprocedurally.
Definition: ValueLatticeUtils.cpp:23