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 | cdf4788401afff02e12279fc1fded94d6180639c (patch) | |
| tree | 4b7b22b5e5b9ee152848a85ca3a911566532ecef /llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | |
| parent | c980afc578f9c1af3b8916b4a503ea26ebaee018 (diff) | |
| download | bcm5719-llvm-cdf4788401afff02e12279fc1fded94d6180639c.tar.gz bcm5719-llvm-cdf4788401afff02e12279fc1fded94d6180639c.zip | |
[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. =]
llvm-svn: 203364
Diffstat (limited to 'llvm/lib/Transforms/IPO/ArgumentPromotion.cpp')
| -rw-r--r-- | llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 54 |
1 files changed, 24 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index fb458a3ef85..48d3fba54f4 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -136,11 +136,10 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) { // transform functions that have indirect callers. Also see if the function // is self-recursive. bool isSelfRecursive = false; - for (Value::use_iterator UI = F->use_begin(), E = F->use_end(); - UI != E; ++UI) { - CallSite CS(*UI); + for (Use &U : F->uses()) { + CallSite CS(U.getUser()); // Must be a direct call. - if (CS.getInstruction() == 0 || !CS.isCallee(UI)) return 0; + if (CS.getInstruction() == 0 || !CS.isCallee(&U)) return 0; if (CS.getInstruction()->getParent()->getParent() == F) isSelfRecursive = true; @@ -222,9 +221,8 @@ static bool AllCallersPassInValidPointerForArgument(Argument *Arg) { // Look at all call sites of the function. At this pointer we know we only // have direct callees. - for (Value::use_iterator UI = Callee->use_begin(), E = Callee->use_end(); - UI != E; ++UI) { - CallSite CS(*UI); + for (User *U : Callee->users()) { + CallSite CS(U); assert(CS && "Should only have direct calls!"); if (!CS.getArgument(ArgNo)->isDereferenceablePointer()) @@ -375,17 +373,16 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, // not (GEP+)loads, or any (GEP+)loads that are not safe to promote. SmallVector<LoadInst*, 16> Loads; IndicesVector Operands; - for (Value::use_iterator UI = Arg->use_begin(), E = Arg->use_end(); - UI != E; ++UI) { - User *U = *UI; + for (Use &U : Arg->uses()) { + User *UR = U.getUser(); Operands.clear(); - if (LoadInst *LI = dyn_cast<LoadInst>(U)) { + if (LoadInst *LI = dyn_cast<LoadInst>(UR)) { // Don't hack volatile/atomic loads if (!LI->isSimple()) return false; Loads.push_back(LI); // Direct loads are equivalent to a GEP with a zero index and then a load. Operands.push_back(0); - } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) { + } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(UR)) { if (GEP->use_empty()) { // Dead GEP's cause trouble later. Just remove them if we run into // them. @@ -406,9 +403,8 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, return false; // Not a constant operand GEP! // Ensure that the only users of the GEP are load instructions. - for (Value::use_iterator UI = GEP->use_begin(), E = GEP->use_end(); - UI != E; ++UI) - if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) { + for (User *GEPU : GEP->users()) + if (LoadInst *LI = dyn_cast<LoadInst>(GEPU)) { // Don't hack volatile/atomic loads if (!LI->isSimple()) return false; Loads.push_back(LI); @@ -554,16 +550,15 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, // In this table, we will track which indices are loaded from the argument // (where direct loads are tracked as no indices). ScalarizeTable &ArgIndices = ScalarizedElements[I]; - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; - ++UI) { - Instruction *User = cast<Instruction>(*UI); - assert(isa<LoadInst>(User) || isa<GetElementPtrInst>(User)); + for (User *U : I->users()) { + Instruction *UI = cast<Instruction>(U); + assert(isa<LoadInst>(UI) || isa<GetElementPtrInst>(UI)); IndicesVector Indices; - Indices.reserve(User->getNumOperands() - 1); + Indices.reserve(UI->getNumOperands() - 1); // Since loads will only have a single operand, and GEPs only a single // non-index operand, this will record direct loads without any indices, // and gep+loads with the GEP indices. - for (User::op_iterator II = User->op_begin() + 1, IE = User->op_end(); + for (User::op_iterator II = UI->op_begin() + 1, IE = UI->op_end(); II != IE; ++II) Indices.push_back(cast<ConstantInt>(*II)->getSExtValue()); // GEPs with a single 0 index can be merged with direct loads @@ -571,11 +566,11 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, Indices.clear(); ArgIndices.insert(Indices); LoadInst *OrigLoad; - if (LoadInst *L = dyn_cast<LoadInst>(User)) + if (LoadInst *L = dyn_cast<LoadInst>(UI)) OrigLoad = L; else // Take any load, we will use it only to update Alias Analysis - OrigLoad = cast<LoadInst>(User->use_back()); + OrigLoad = cast<LoadInst>(UI->user_back()); OriginalLoads[std::make_pair(I, Indices)] = OrigLoad; } @@ -636,7 +631,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, // SmallVector<Value*, 16> Args; while (!F->use_empty()) { - CallSite CS(F->use_back()); + CallSite CS(F->user_back()); assert(CS.getCalledFunction() == F); Instruction *Call = CS.getInstruction(); const AttributeSet &CallPAL = CS.getAttributes(); @@ -815,9 +810,8 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, // If the alloca is used in a call, we must clear the tail flag since // the callee now uses an alloca from the caller. - for (Value::use_iterator UI = TheAlloca->use_begin(), - E = TheAlloca->use_end(); UI != E; ++UI) { - CallInst *Call = dyn_cast<CallInst>(*UI); + for (User *U : TheAlloca->users()) { + CallInst *Call = dyn_cast<CallInst>(U); if (!Call) continue; Call->setTailCall(false); @@ -836,7 +830,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, ScalarizeTable &ArgIndices = ScalarizedElements[I]; while (!I->use_empty()) { - if (LoadInst *LI = dyn_cast<LoadInst>(I->use_back())) { + if (LoadInst *LI = dyn_cast<LoadInst>(I->user_back())) { assert(ArgIndices.begin()->empty() && "Load element should sort to front!"); I2->setName(I->getName()+".val"); @@ -846,7 +840,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, DEBUG(dbgs() << "*** Promoted load of argument '" << I->getName() << "' in function '" << F->getName() << "'\n"); } else { - GetElementPtrInst *GEP = cast<GetElementPtrInst>(I->use_back()); + GetElementPtrInst *GEP = cast<GetElementPtrInst>(I->user_back()); IndicesVector Operands; Operands.reserve(GEP->getNumIndices()); for (User::op_iterator II = GEP->idx_begin(), IE = GEP->idx_end(); @@ -876,7 +870,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, // All of the uses must be load instructions. Replace them all with // the argument specified by ArgNo. while (!GEP->use_empty()) { - LoadInst *L = cast<LoadInst>(GEP->use_back()); + LoadInst *L = cast<LoadInst>(GEP->user_back()); L->replaceAllUsesWith(TheArg); AA.replaceWithNewValue(L, TheArg); L->eraseFromParent(); |

