From: Chris Lattner Date: Mon, 29 Apr 2002 01:22:55 +0000 (+0000) Subject: Code cleanups X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2f6f03bddd1811c3e18cf4710e69c981b8d7de60;p=oota-llvm.git Code cleanups git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2391 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp b/lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp index f901a29015d..f4bb51a02d1 100644 --- a/lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp +++ b/lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp @@ -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 @@ -17,6 +17,41 @@ #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(*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, @@ -28,160 +63,109 @@ // 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(*BBI); BasicBlock* BB = memI->getParent(); Value* lastPtr = memI->getPointerOperand(); + + // Remove the instruction from the stream + BB->getInstList().remove(BBI); + vector 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(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(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(*OI) && - cast(*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(*OI) && + cast(*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 idxVec(1, *OI); - PointerType* ptrType = cast(lastPtr->getType()); - if (isa(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 idxVec(1, *OI); + PointerType* ptrType = cast(lastPtr->getType()); + if (isa(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(nextType) || isa(nextType)); + + // Get a pointer to the structure or to the elements of the array. + const Type* nextPtrType = + PointerType::get(isa(nextType) ? nextType + : cast(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(nextType) || isa(nextType)); - - // Get a pointer to the structure or to the elements of the array. - const Type* nextPtrType = - PointerType::get(isa(nextType)? nextType - : cast(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(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(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(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(castInst)); } + + lastPtr = castInst; + } // // Now create a new instruction to replace the original one // - PointerType* ptrType = cast(lastPtr->getType()); - assert(ptrType); + PointerType *ptrType = cast(lastPtr->getType()); // First, get the final index vector. As above, we may need an initial [0]. vector idxVec(1, *OI); if (isa(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(*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()); }