Code cleanups
authorChris Lattner <sabre@nondot.org>
Mon, 29 Apr 2002 01:22:55 +0000 (01:22 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 29 Apr 2002 01:22:55 +0000 (01:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2391 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp

index f901a29015d507477203f28100d5632d49e3d88e..f4bb51a02d1fbac66a7a64d1a03c6a8fd3183731 100644 (file)
@@ -1,4 +1,4 @@
-//===- llvm/Transforms/DecomposeMultiDimRefs.cpp - Lower array refs to 1D ---=//
+//===- llvm/Transforms/DecomposeMultiDimRefs.cpp - Lower array refs to 1D -===//
 //
 // DecomposeMultiDimRefs - 
 // Convert multi-dimensional references consisting of any combination
 #include "llvm/Function.h"
 #include "llvm/Pass.h"
 
+namespace {
+  struct DecomposePass : public BasicBlockPass {
+    virtual bool runOnBasicBlock(BasicBlock *BB);
+
+  private:
+    static void decomposeArrayRef(BasicBlock::iterator &BBI);
+  };
+}
+
+Pass *createDecomposeMultiDimRefsPass() {
+  return new DecomposePass();
+}
+
+
+// runOnBasicBlock - Entry point for array or structure references with multiple
+// indices.
+//
+bool DecomposePass::runOnBasicBlock(BasicBlock *BB) {
+  bool Changed = false;
+  
+  for (BasicBlock::iterator II = BB->begin(); II != BB->end(); ) {
+    if (MemAccessInst *MAI = dyn_cast<MemAccessInst>(*II)) {
+      if (MAI->getNumOperands() > MAI->getFirstIndexOperandNumber()+1) {
+        decomposeArrayRef(II);
+        Changed = true;
+      } else {
+        ++II;
+      }
+    } else {
+      ++II;
+    }
+  }
+  
+  return Changed;
+}
 
 // 
 // For any combination of 2 or more array and structure indices,
 // uses the last ptr2 generated in the loop and a single index.
 // If any index is (uint) 0, we omit the getElementPtr instruction.
 // 
-static BasicBlock::iterator
-decomposeArrayRef(BasicBlock::iterator& BBI)
-{
+void DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI){
   MemAccessInst *memI = cast<MemAccessInst>(*BBI);
   BasicBlock* BB = memI->getParent();
   Value* lastPtr = memI->getPointerOperand();
+
+  // Remove the instruction from the stream
+  BB->getInstList().remove(BBI);
+
   vector<Instruction*> newIvec;
   
   // Process each index except the last one.
   // 
-  MemAccessInst::const_op_iterator OI = memI->idx_begin();
-  MemAccessInst::const_op_iterator OE = memI->idx_end();
-  for ( ; OI != OE; ++OI)
-    {
-      assert(isa<PointerType>(lastPtr->getType()));
-      
-      if (OI+1 == OE)                   // stop before the last operand
-        break;
+  User::const_op_iterator OI = memI->idx_begin(), OE = memI->idx_end();
+  for (; OI != OE && OI+1 != OE; ++OI) {
+    assert(isa<PointerType>(lastPtr->getType()));
       
-      // Check for a zero index.  This will need a cast instead of
-      // a getElementPtr, or it may need neither.
-      bool indexIsZero = bool(isa<ConstantUInt>(*OI) && 
-                              cast<ConstantUInt>(*OI)->getValue() == 0);
+    // Check for a zero index.  This will need a cast instead of
+    // a getElementPtr, or it may need neither.
+    bool indexIsZero = isa<ConstantUInt>(*OI) && 
+                       cast<Constant>(*OI)->isNullValue();
       
-      // Extract the first index.  If the ptr is a pointer to a structure
-      // and the next index is a structure offset (i.e., not an array offset), 
-      // we need to include an initial [0] to index into the pointer.
-      vector<Value*> idxVec(1, *OI);
-      PointerType* ptrType = cast<PointerType>(lastPtr->getType());
-      if (isa<StructType>(ptrType->getElementType())
-          && ! ptrType->indexValid(*OI))
-        idxVec.insert(idxVec.begin(), ConstantUInt::get(Type::UIntTy, 0));
+    // Extract the first index.  If the ptr is a pointer to a structure
+    // and the next index is a structure offset (i.e., not an array offset), 
+    // we need to include an initial [0] to index into the pointer.
+    vector<Value*> idxVec(1, *OI);
+    PointerType* ptrType = cast<PointerType>(lastPtr->getType());
+    if (isa<StructType>(ptrType->getElementType())
+        && ! ptrType->indexValid(*OI))
+      idxVec.insert(idxVec.begin(), ConstantUInt::get(Type::UIntTy, 0));
+    
+    // Get the type obtained by applying the first index.
+    // It must be a structure or array.
+    const Type* nextType = MemAccessInst::getIndexedType(lastPtr->getType(),
+                                                         idxVec, true);
+    assert(isa<StructType>(nextType) || isa<ArrayType>(nextType));
+    
+    // Get a pointer to the structure or to the elements of the array.
+    const Type* nextPtrType =
+      PointerType::get(isa<StructType>(nextType) ? nextType
+                       : cast<ArrayType>(nextType)->getElementType());
       
-      // Get the type obtained by applying the first index.
-      // It must be a structure or array.
-      const Type* nextType = MemAccessInst::getIndexedType(lastPtr->getType(),
-                                                           idxVec, true);
-      assert(isa<StructType>(nextType) || isa<ArrayType>(nextType));
-      
-      // Get a pointer to the structure or to the elements of the array.
-      const Type* nextPtrType =
-        PointerType::get(isa<StructType>(nextType)? nextType
-                         : cast<ArrayType>(nextType)->getElementType());
-      
-      // Instruction 1: nextPtr1 = GetElementPtr lastPtr, idxVec
-      // This is not needed if the index is zero.
-      Value* gepValue;
-      if (indexIsZero)
-        gepValue = lastPtr;
-      else
-        {
-          gepValue = new GetElementPtrInst(lastPtr, idxVec,"ptr1");
-          newIvec.push_back(cast<Instruction>(gepValue));
-        }
-      
-      // Instruction 2: nextPtr2 = cast nextPtr1 to nextPtrType
-      // This is not needed if the two types are identical.
-      Value* castInst;
-      if (gepValue->getType() == nextPtrType)
-        castInst = gepValue;
-      else
-        {
-          castInst = new CastInst(gepValue, nextPtrType, "ptr2");
-          newIvec.push_back(cast<Instruction>(castInst));
-        }
+    // Instruction 1: nextPtr1 = GetElementPtr lastPtr, idxVec
+    // This is not needed if the index is zero.
+    Value *gepValue;
+    if (indexIsZero)
+      gepValue = lastPtr;
+    else {
+      gepValue = new GetElementPtrInst(lastPtr, idxVec,"ptr1");
+      newIvec.push_back(cast<Instruction>(gepValue));
+    }
       
-      lastPtr = castInst;
+    // Instruction 2: nextPtr2 = cast nextPtr1 to nextPtrType
+    // This is not needed if the two types are identical.
+    Value *castInst;
+    if (gepValue->getType() == nextPtrType)
+      castInst = gepValue;
+    else {
+      castInst = new CastInst(gepValue, nextPtrType, "ptr2");
+      newIvec.push_back(cast<Instruction>(castInst));
     }
+      
+    lastPtr = castInst;
+  }
   
   // 
   // Now create a new instruction to replace the original one
   //
-  PointerType* ptrType = cast<PointerType>(lastPtr->getType());
-  assert(ptrType);
+  PointerType *ptrType = cast<PointerType>(lastPtr->getType());
 
   // First, get the final index vector.  As above, we may need an initial [0].
   vector<Value*> idxVec(1, *OI);
   if (isa<StructType>(ptrType->getElementType())
-      && ! ptrType->indexValid(*OI))
-    idxVec.insert(idxVec.begin(), ConstantUInt::get(Type::UIntTy, 0));
+      && !ptrType->indexValid(*OI))
+    idxVec.insert(idxVec.begin(), Constant::getNullValue(Type::UIntTy));
   
-  const std::string newInstName = memI->hasName()? memI->getName()
-                                                 : string("finalRef");
   Instruction* newInst = NULL;
-  
-  switch(memI->getOpcode())
-    {
-    case Instruction::Load:
-      newInst = new LoadInst(lastPtr, idxVec /*, newInstName */); break;
-    case Instruction::Store:
-      newInst = new StoreInst(memI->getOperand(0),
-                              lastPtr, idxVec /*, newInstName */); break;
-      break;
-    case Instruction::GetElementPtr:
-      newInst = new GetElementPtrInst(lastPtr, idxVec /*, newInstName */); break;
-    default:
-      assert(0 && "Unrecognized memory access instruction"); break;
-    }
-  
+  switch(memI->getOpcode()) {
+  case Instruction::Load:
+    newInst = new LoadInst(lastPtr, idxVec, memI->getName());
+    break;
+  case Instruction::Store:
+    newInst = new StoreInst(memI->getOperand(0), lastPtr, idxVec);
+    break;
+  case Instruction::GetElementPtr:
+    newInst = new GetElementPtrInst(lastPtr, idxVec, memI->getName());
+    break;
+  default:
+    assert(0 && "Unrecognized memory access instruction");
+  }
   newIvec.push_back(newInst);
   
   // Replace all uses of the old instruction with the new
   memI->replaceAllUsesWith(newInst);
-  
-  BasicBlock::iterator newI = BBI;;
-  for (int i = newIvec.size()-1; i >= 0; i--)
-    newI = BB->getInstList().insert(newI, newIvec[i]);
-  
-  // Now delete the old instruction and return a pointer to the last new one
-  BB->getInstList().remove(memI);
-  delete memI;
-  
-  return newI + newIvec.size() - 1;           // pointer to last new instr
-}
 
+  // Now delete the old instruction...
+  delete memI;
 
-//---------------------------------------------------------------------------
-// Entry point for array or  structure references with multiple indices.
-//---------------------------------------------------------------------------
+  // Convert our iterator into an index... that cannot get invalidated
+  unsigned ItOffs = BBI-BB->begin();
 
-static bool
-doDecomposeMultiDimRefs(Function *F)
-{
-  bool changed = false;
-  
-  for (Function::iterator BI = F->begin(), BE = F->end(); BI != BE; ++BI)
-    for (BasicBlock::iterator newI, II = (*BI)->begin();
-         II != (*BI)->end(); II = ++newI)
-      {
-        newI = II;
-        if (MemAccessInst *memI = dyn_cast<MemAccessInst>(*II))
-          if (memI->getNumOperands() > 1 + memI->getFirstIndexOperandNumber())
-            {
-              newI = decomposeArrayRef(II);
-              changed = true;
-            }
-      }
+  // Insert all of the new instructions...
+  BB->getInstList().insert(BBI, newIvec.begin(), newIvec.end());
   
-  return changed;
-}
-
-
-namespace {
-  struct DecomposeMultiDimRefsPass : public FunctionPass {
-    virtual bool runOnFunction(Function *F) {
-      return doDecomposeMultiDimRefs(F);
-    }
-
-    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      AU.preservesCFG();
-    }
-  };
-}
-
-Pass *createDecomposeMultiDimRefsPass() {
-  return new DecomposeMultiDimRefsPass();
+  // Advance the iterator to the instruction following the one just inserted...
+  BBI = BB->begin() + (ItOffs+newIvec.size());
 }