summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Value.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Value.cpp')
-rw-r--r--llvm/lib/IR/Value.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 69a84d72cac..2f95e9348b4 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -465,6 +465,35 @@ void Value::replaceUsesOutsideBlock(Value *New, BasicBlock *BB) {
}
}
+void Value::replaceUsesExceptBlockAddr(Value *New) {
+ SmallSetVector<Constant *, 4> Constants;
+ use_iterator UI = use_begin(), E = use_end();
+ for (; UI != E;) {
+ Use &U = *UI;
+ ++UI;
+
+ if (isa<BlockAddress>(U.getUser()))
+ continue;
+
+ // Must handle Constants specially, we cannot call replaceUsesOfWith on a
+ // constant because they are uniqued.
+ if (auto *C = dyn_cast<Constant>(U.getUser())) {
+ if (!isa<GlobalValue>(C)) {
+ // Save unique users to avoid processing operand replacement
+ // more than once.
+ Constants.insert(C);
+ continue;
+ }
+ }
+
+ U.set(New);
+ }
+
+ // Process operand replacement of saved constants.
+ for (auto *C : Constants)
+ C->handleOperandChange(this, New);
+}
+
namespace {
// Various metrics for how much to strip off of pointers.
enum PointerStripKind {
OpenPOWER on IntegriCloud