aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Analysis/LazyCallGraph.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
commite6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch)
tree599ab169a01f1c86eda9adc774edaedde2f2db5b /include/llvm/Analysis/LazyCallGraph.h
parent1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff)
Diffstat (limited to 'include/llvm/Analysis/LazyCallGraph.h')
-rw-r--r--include/llvm/Analysis/LazyCallGraph.h32
1 files changed, 23 insertions, 9 deletions
diff --git a/include/llvm/Analysis/LazyCallGraph.h b/include/llvm/Analysis/LazyCallGraph.h
index d1ec6a9dcc55..2d83929211e2 100644
--- a/include/llvm/Analysis/LazyCallGraph.h
+++ b/include/llvm/Analysis/LazyCallGraph.h
@@ -1,9 +1,8 @@
//===- LazyCallGraph.h - Analysis of a Module's call graph ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -39,6 +38,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -1083,12 +1083,26 @@ public:
continue;
}
+ // The blockaddress constant expression is a weird special case, we can't
+ // generically walk its operands the way we do for all other constants.
if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
- // The blockaddress constant expression is a weird special case, we
- // can't generically walk its operands the way we do for all other
- // constants.
- if (Visited.insert(BA->getFunction()).second)
- Worklist.push_back(BA->getFunction());
+ // If we've already visited the function referred to by the block
+ // address, we don't need to revisit it.
+ if (Visited.count(BA->getFunction()))
+ continue;
+
+ // If all of the blockaddress' users are instructions within the
+ // referred to function, we don't need to insert a cycle.
+ if (llvm::all_of(BA->users(), [&](User *U) {
+ if (Instruction *I = dyn_cast<Instruction>(U))
+ return I->getFunction() == BA->getFunction();
+ return false;
+ }))
+ continue;
+
+ // Otherwise we should go visit the referred to function.
+ Visited.insert(BA->getFunction());
+ Worklist.push_back(BA->getFunction());
continue;
}