diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2014-03-09 03:16:01 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2014-03-09 03:16:01 +0000 |
commit | 36b699f2b139a30a2dfa4448223d6985b55daa8a (patch) | |
tree | d6844c991f0c06de4b66a2615259607d8349e5b3 /lib/IR | |
parent | b033b03c23fb3ae066937b2ec09eb9d7a3f1d522 (diff) | |
download | llvm-36b699f2b139a30a2dfa4448223d6985b55daa8a.tar.gz llvm-36b699f2b139a30a2dfa4448223d6985b55daa8a.tar.bz2 llvm-36b699f2b139a30a2dfa4448223d6985b55daa8a.tar.xz |
[C++11] Add range based accessors for the Use-Def chain of a Value.
This requires a number of steps.
1) Move value_use_iterator into the Value class as an implementation
detail
2) Change it to actually be a *Use* iterator rather than a *User*
iterator.
3) Add an adaptor which is a User iterator that always looks through the
Use to the User.
4) Wrap these in Value::use_iterator and Value::user_iterator typedefs.
5) Add the range adaptors as Value::uses() and Value::users().
6) Update *all* of the callers to correctly distinguish between whether
they wanted a use_iterator (and to explicitly dig out the User when
needed), or a user_iterator which makes the Use itself totally
opaque.
Because #6 requires churning essentially everything that walked the
Use-Def chains, I went ahead and added all of the range adaptors and
switched them to range-based loops where appropriate. Also because the
renaming requires at least churning every line of code, it didn't make
any sense to split these up into multiple commits -- all of which would
touch all of the same lies of code.
The result is still not quite optimal. The Value::use_iterator is a nice
regular iterator, but Value::user_iterator is an iterator over User*s
rather than over the User objects themselves. As a consequence, it fits
a bit awkwardly into the range-based world and it has the weird
extra-dereferencing 'operator->' that so many of our iterators have.
I think this could be fixed by providing something which transforms
a range of T&s into a range of T*s, but that *can* be separated into
another patch, and it isn't yet 100% clear whether this is the right
move.
However, this change gets us most of the benefit and cleans up
a substantial amount of code around Use and User. =]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203364 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/AutoUpgrade.cpp | 2 | ||||
-rw-r--r-- | lib/IR/BasicBlock.cpp | 2 | ||||
-rw-r--r-- | lib/IR/Constants.cpp | 16 | ||||
-rw-r--r-- | lib/IR/Core.cpp | 2 | ||||
-rw-r--r-- | lib/IR/DebugInfo.cpp | 4 | ||||
-rw-r--r-- | lib/IR/Function.cpp | 20 | ||||
-rw-r--r-- | lib/IR/Instruction.cpp | 10 | ||||
-rw-r--r-- | lib/IR/Value.cpp | 2 | ||||
-rw-r--r-- | lib/IR/Verifier.cpp | 12 |
9 files changed, 34 insertions, 36 deletions
diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index ca44143307..b7429b30f5 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -411,7 +411,7 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { if (UpgradeIntrinsicFunction(F, NewFn)) { if (NewFn != F) { // Replace all uses to the old function with the new one if necessary. - for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); + for (Value::user_iterator UI = F->user_begin(), UE = F->user_end(); UI != UE; ) { if (CallInst *CI = dyn_cast<CallInst>(*UI++)) UpgradeIntrinsicCall(CI, NewFn); diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp index ef264d27fc..3079f0ad08 100644 --- a/lib/IR/BasicBlock.cpp +++ b/lib/IR/BasicBlock.cpp @@ -74,7 +74,7 @@ BasicBlock::~BasicBlock() { Constant *Replacement = ConstantInt::get(llvm::Type::getInt32Ty(getContext()), 1); while (!use_empty()) { - BlockAddress *BA = cast<BlockAddress>(use_back()); + BlockAddress *BA = cast<BlockAddress>(user_back()); BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement, BA->getType())); BA->destroyConstant(); diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index 944402558f..2a3a5fdf13 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -218,7 +218,7 @@ void Constant::destroyConstantImpl() { // Constants) that they are, in fact, invalid now and should be deleted. // while (!use_empty()) { - Value *V = use_back(); + Value *V = user_back(); #ifndef NDEBUG // Only in -g mode... if (!isa<Constant>(V)) { dbgs() << "While deleting: " << *this @@ -230,7 +230,7 @@ void Constant::destroyConstantImpl() { cast<Constant>(V)->destroyConstant(); // The constant should remove itself from our use list... - assert((use_empty() || use_back() != V) && "Constant not removed!"); + assert((use_empty() || user_back() != V) && "Constant not removed!"); } // Value has no outstanding references it is safe to delete it now... @@ -307,8 +307,8 @@ bool Constant::isThreadDependent() const { /// isConstantUsed - Return true if the constant has users other than constant /// exprs and other dangling things. bool Constant::isConstantUsed() const { - for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { - const Constant *UC = dyn_cast<Constant>(*UI); + for (const User *U : users()) { + const Constant *UC = dyn_cast<Constant>(U); if (UC == 0 || isa<GlobalValue>(UC)) return true; @@ -377,7 +377,7 @@ static bool removeDeadUsersOfConstant(const Constant *C) { if (isa<GlobalValue>(C)) return false; // Cannot remove this while (!C->use_empty()) { - const Constant *User = dyn_cast<Constant>(C->use_back()); + const Constant *User = dyn_cast<Constant>(C->user_back()); if (!User) return false; // Non-constant usage; if (!removeDeadUsersOfConstant(User)) return false; // Constant wasn't dead @@ -393,8 +393,8 @@ static bool removeDeadUsersOfConstant(const Constant *C) { /// that want to check to see if a global is unused, but don't want to deal /// with potentially dead constants hanging off of the globals. void Constant::removeDeadConstantUsers() const { - Value::const_use_iterator I = use_begin(), E = use_end(); - Value::const_use_iterator LastNonDeadUser = E; + Value::const_user_iterator I = user_begin(), E = user_end(); + Value::const_user_iterator LastNonDeadUser = E; while (I != E) { const Constant *User = dyn_cast<Constant>(*I); if (User == 0) { @@ -413,7 +413,7 @@ void Constant::removeDeadConstantUsers() const { // If the constant was dead, then the iterator is invalidated. if (LastNonDeadUser == E) { - I = use_begin(); + I = user_begin(); if (I == E) break; } else { I = LastNonDeadUser; diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index 6c012736de..0c2e31a0b0 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -514,7 +514,7 @@ LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) { Value::use_iterator I = V->use_begin(); if (I == V->use_end()) return 0; - return wrap(&(I.getUse())); + return wrap(&*I); } LLVMUseRef LLVMGetNextUse(LLVMUseRef U) { diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index 4e9d1d1c2e..d69138e057 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -1476,7 +1476,7 @@ bool llvm::StripDebugInfo(Module &M) { // the module. if (Function *Declare = M.getFunction("llvm.dbg.declare")) { while (!Declare->use_empty()) { - CallInst *CI = cast<CallInst>(Declare->use_back()); + CallInst *CI = cast<CallInst>(Declare->user_back()); CI->eraseFromParent(); } Declare->eraseFromParent(); @@ -1485,7 +1485,7 @@ bool llvm::StripDebugInfo(Module &M) { if (Function *DbgVal = M.getFunction("llvm.dbg.value")) { while (!DbgVal->use_empty()) { - CallInst *CI = cast<CallInst>(DbgVal->use_back()); + CallInst *CI = cast<CallInst>(DbgVal->user_back()); CI->eraseFromParent(); } DbgVal->eraseFromParent(); diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index 72f38c5475..865970c469 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -711,15 +711,15 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) { /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. bool Function::hasAddressTaken(const User* *PutOffender) const { - for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) { - const User *U = *I; - if (isa<BlockAddress>(U)) + for (const Use &U : uses()) { + const User *FU = U.getUser(); + if (isa<BlockAddress>(FU)) continue; - if (!isa<CallInst>(U) && !isa<InvokeInst>(U)) - return PutOffender ? (*PutOffender = U, true) : true; - ImmutableCallSite CS(cast<Instruction>(U)); - if (!CS.isCallee(I)) - return PutOffender ? (*PutOffender = U, true) : true; + if (!isa<CallInst>(FU) && !isa<InvokeInst>(FU)) + return PutOffender ? (*PutOffender = FU, true) : true; + ImmutableCallSite CS(cast<Instruction>(FU)); + if (!CS.isCallee(&U)) + return PutOffender ? (*PutOffender = FU, true) : true; } return false; } @@ -731,8 +731,8 @@ bool Function::isDefTriviallyDead() const { return false; // Check if the function is used by anything other than a blockaddress. - for (Value::const_use_iterator I = use_begin(), E = use_end(); I != E; ++I) - if (!isa<BlockAddress>(*I)) + for (const User *U : users()) + if (!isa<BlockAddress>(U)) return false; return true; diff --git a/lib/IR/Instruction.cpp b/lib/IR/Instruction.cpp index 4bcf7484d6..67aa8b2818 100644 --- a/lib/IR/Instruction.cpp +++ b/lib/IR/Instruction.cpp @@ -403,18 +403,18 @@ bool Instruction::isSameOperationAs(const Instruction *I, /// specified block. Note that PHI nodes are considered to evaluate their /// operands in the corresponding predecessor block. bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { - for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { + for (const Use &U : uses()) { // PHI nodes uses values in the corresponding predecessor block. For other // instructions, just check to see whether the parent of the use matches up. - const User *U = *UI; - const PHINode *PN = dyn_cast<PHINode>(U); + const Instruction *I = cast<Instruction>(U.getUser()); + const PHINode *PN = dyn_cast<PHINode>(I); if (PN == 0) { - if (cast<Instruction>(U)->getParent() != BB) + if (I->getParent() != BB) return true; continue; } - if (PN->getIncomingBlock(UI) != BB) + if (PN->getIncomingBlock(U) != BB) return true; } return false; diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index bdb544bef4..97a562e3e5 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -119,7 +119,7 @@ bool Value::isUsedInBasicBlock(const BasicBlock *BB) const { // Scan both lists simultaneously until one is exhausted. This limits the // search to the shorter list. BasicBlock::const_iterator BI = BB->begin(), BE = BB->end(); - const_use_iterator UI = use_begin(), UE = use_end(); + const_user_iterator UI = user_begin(), UE = user_end(); for (; BI != BE && UI != UE; ++BI, ++UI) { // Scan basic block: Check if this Value is used by the instruction at BI. if (std::find(BI->op_begin(), BI->op_end(), this) != BI->op_end()) diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index deb708da17..f64ebc1a67 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -1974,9 +1974,8 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(BB, "Instruction not embedded in basic block!", &I); if (!isa<PHINode>(I)) { // Check that non-phi nodes are not self referential - for (Value::use_iterator UI = I.use_begin(), UE = I.use_end(); - UI != UE; ++UI) - Assert1(*UI != (User*)&I || !DT.isReachableFromEntry(BB), + for (User *U : I.users()) + Assert1(U != (User*)&I || !DT.isReachableFromEntry(BB), "Only PHI nodes may reference their own value!", &I); } @@ -1999,13 +1998,12 @@ void Verifier::visitInstruction(Instruction &I) { // Check that all uses of the instruction, if they are instructions // themselves, actually have parent basic blocks. If the use is not an // instruction, it is an error! - for (User::use_iterator UI = I.use_begin(), UE = I.use_end(); - UI != UE; ++UI) { - if (Instruction *Used = dyn_cast<Instruction>(*UI)) + for (Use &U : I.uses()) { + if (Instruction *Used = dyn_cast<Instruction>(U.getUser())) Assert2(Used->getParent() != 0, "Instruction referencing instruction not" " embedded in a basic block!", &I, Used); else { - CheckFailed("Use of instruction is not an instruction!", *UI); + CheckFailed("Use of instruction is not an instruction!", U); return; } } |