summaryrefslogtreecommitdiff
path: root/lib/IR/Value.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/IR/Value.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/IR/Value.cpp')
-rw-r--r--lib/IR/Value.cpp51
1 files changed, 42 insertions, 9 deletions
diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp
index 51a7d424c1f3..eae697b2e4b9 100644
--- a/lib/IR/Value.cpp
+++ b/lib/IR/Value.cpp
@@ -15,6 +15,7 @@
#include "LLVMContextImpl.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
@@ -50,6 +51,7 @@ Value::Value(Type *ty, unsigned scid)
: VTy(checkType(ty)), UseList(nullptr), SubclassID(scid),
HasValueHandle(0), SubclassOptionalData(0), SubclassData(0),
NumUserOperands(0), IsUsedByMD(false), HasName(false) {
+ static_assert(ConstantFirstVal == 0, "!(SubclassID < ConstantFirstVal)");
// FIXME: Why isn't this in the subclass gunk??
// Note, we cannot call isa<CallInst> before the CallInst has been
// constructed.
@@ -57,7 +59,7 @@ Value::Value(Type *ty, unsigned scid)
assert((VTy->isFirstClassType() || VTy->isVoidTy() || VTy->isStructTy()) &&
"invalid CallInst type!");
else if (SubclassID != BasicBlockVal &&
- (SubclassID < ConstantFirstVal || SubclassID > ConstantLastVal))
+ (/*SubclassID < ConstantFirstVal ||*/ SubclassID > ConstantLastVal))
assert((VTy->isFirstClassType() || VTy->isVoidTy()) &&
"Cannot create non-first-class values except for constants!");
static_assert(sizeof(Value) == 2 * sizeof(void *) + 2 * sizeof(unsigned),
@@ -407,7 +409,7 @@ void Value::doRAUW(Value *New, bool NoMetadata) {
if (!NoMetadata && isUsedByMetadata())
ValueAsMetadata::handleRAUW(this, New);
- while (!use_empty()) {
+ while (!materialized_use_empty()) {
Use &U = *UseList;
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
// constant because they are uniqued.
@@ -454,6 +456,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 {
@@ -588,17 +619,17 @@ const Value *Value::stripInBoundsOffsets() const {
return stripPointerCastsAndOffsets<PSK_InBounds>(this);
}
-unsigned Value::getPointerDereferenceableBytes(const DataLayout &DL,
+uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL,
bool &CanBeNull) const {
assert(getType()->isPointerTy() && "must be pointer");
- unsigned DerefBytes = 0;
+ uint64_t DerefBytes = 0;
CanBeNull = false;
if (const Argument *A = dyn_cast<Argument>(this)) {
DerefBytes = A->getDereferenceableBytes();
- if (DerefBytes == 0 && A->hasByValAttr() && A->getType()->isSized()) {
- DerefBytes = DL.getTypeStoreSize(A->getType());
- CanBeNull = false;
+ if (DerefBytes == 0 && A->hasByValAttr()) {
+ Type *PT = cast<PointerType>(A->getType())->getElementType();
+ DerefBytes = DL.getTypeStoreSize(PT);
}
if (DerefBytes == 0) {
DerefBytes = A->getDereferenceableOrNullBytes();
@@ -624,8 +655,10 @@ unsigned Value::getPointerDereferenceableBytes(const DataLayout &DL,
CanBeNull = true;
}
} else if (auto *AI = dyn_cast<AllocaInst>(this)) {
- if (AI->getAllocatedType()->isSized()) {
- DerefBytes = DL.getTypeStoreSize(AI->getAllocatedType());
+ const ConstantInt *ArraySize = dyn_cast<ConstantInt>(AI->getArraySize());
+ if (ArraySize && AI->getAllocatedType()->isSized()) {
+ DerefBytes = DL.getTypeStoreSize(AI->getAllocatedType()) *
+ ArraySize->getZExtValue();
CanBeNull = false;
}
} else if (auto *GV = dyn_cast<GlobalVariable>(this)) {