[C++11] Add two range adaptor views to User: operands and
authorChandler Carruth <chandlerc@gmail.com>
Mon, 3 Mar 2014 10:42:58 +0000 (10:42 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Mon, 3 Mar 2014 10:42:58 +0000 (10:42 +0000)
operand_values. The first provides a range view over operand Use
objects, and the second provides a range view over the Value*s being
used by those operands.

The naming is "STL-style" rather than "LLVM-style" because we have
historically named iterator methods STL-style, and range methods seem to
have far more in common with their iterator counterparts than with
"normal" APIs. Feel free to bikeshed on this one if you want, I'm happy
to change these around if people feel strongly.

I've switched code in SROA and LCG to exercise these mostly to ensure
they work correctly -- we don't really have an easy way to unittest this
and they're trivial.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202687 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/User.h
lib/Analysis/LazyCallGraph.cpp
lib/Transforms/Scalar/SROA.cpp

index 505bdeb178e9dbac1390a1a5cfb44c0e75d3564e..7d3fb494adddf51f2bb9e3774e92b88cd56bbfd9 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef LLVM_IR_USER_H
 #define LLVM_IR_USER_H
 
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/IR/Value.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -112,11 +113,19 @@ public:
   //
   typedef Use*       op_iterator;
   typedef const Use* const_op_iterator;
+  typedef iterator_range<op_iterator> op_range;
+  typedef iterator_range<const_op_iterator> const_op_range;
 
   inline op_iterator       op_begin()       { return OperandList; }
   inline const_op_iterator op_begin() const { return OperandList; }
   inline op_iterator       op_end()         { return OperandList+NumOperands; }
   inline const_op_iterator op_end()   const { return OperandList+NumOperands; }
+  inline op_range operands() {
+    return {op_begin(), op_end()};
+  }
+  inline const_op_range operands() const {
+    return {op_begin(), op_end()};
+  }
 
   /// Convenience iterator for directly iterating over the Values in the
   /// OperandList
@@ -156,6 +165,9 @@ public:
   inline value_op_iterator value_op_end() {
     return value_op_iterator(op_end());
   }
+  inline iterator_range<value_op_iterator> operand_values() {
+    return {value_op_begin(), value_op_end()};
+  }
 
   // dropAllReferences() - This function is in charge of "letting go" of all
   // objects that this User refers to.  This allows one to
index 9e0559829dec065d3c04203c4d60e8579821f4e5..74eef7b68f6b9b414e30554115324b50d12408e7 100644 (file)
@@ -40,11 +40,9 @@ static void findCallees(
       continue;
     }
 
-    for (User::value_op_iterator OI = C->value_op_begin(),
-                                 OE = C->value_op_end();
-         OI != OE; ++OI)
-      if (Visited.insert(cast<Constant>(*OI)))
-        Worklist.push_back(cast<Constant>(*OI));
+    for (Value *Op : C->operand_values())
+      if (Visited.insert(cast<Constant>(Op)))
+        Worklist.push_back(cast<Constant>(Op));
   }
 }
 
@@ -56,10 +54,8 @@ LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F) : G(G), F(F) {
   for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
     for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
          ++II)
-      for (User::value_op_iterator OI = II->value_op_begin(),
-                                   OE = II->value_op_end();
-           OI != OE; ++OI)
-        if (Constant *C = dyn_cast<Constant>(*OI))
+      for (Value *Op : II->operand_values())
+        if (Constant *C = dyn_cast<Constant>(Op))
           if (Visited.insert(C))
             Worklist.push_back(C);
 
index 1cb76696f18301efd11a3e0db2e326af085342fe..3c245e4bd5e49717cbbbfbfdbe62ea5b018aa811 100644 (file)
@@ -3447,9 +3447,8 @@ bool SROA::runOnAlloca(AllocaInst &AI) {
                                         DE = S.dead_user_end();
        DI != DE; ++DI) {
     // Free up everything used by this instruction.
-    for (User::op_iterator DOI = (*DI)->op_begin(), DOE = (*DI)->op_end();
-         DOI != DOE; ++DOI)
-      clobberUse(*DOI);
+    for (Use &DeadOp : (*DI)->operands())
+      clobberUse(DeadOp);
 
     // Now replace the uses of this instruction.
     (*DI)->replaceAllUsesWith(UndefValue::get((*DI)->getType()));
@@ -3498,10 +3497,10 @@ void SROA::deleteDeadInstructions(SmallPtrSet<AllocaInst*, 4> &DeletedAllocas) {
 
     I->replaceAllUsesWith(UndefValue::get(I->getType()));
 
-    for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI)
-      if (Instruction *U = dyn_cast<Instruction>(*OI)) {
+    for (Use &Operand : I->operands())
+      if (Instruction *U = dyn_cast<Instruction>(Operand)) {
         // Zero out the operand and see if it becomes trivially dead.
-        *OI = 0;
+        Operand = 0;
         if (isInstructionTriviallyDead(U))
           DeadInsts.insert(U);
       }