From e99c66b74fe04aeebeeb1b0c50ed0ea5ba45d371 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 1 Nov 2001 17:05:27 +0000 Subject: [PATCH] * Add comments for peepholes * Implement new peephole: // Peephole optimize the following instructions: // %t1 = cast {<...>} * %StructPtr to * // // Into: %t2 = getelementptr {<...>} * %StructPtr, <0, 0, 0, ...> // %t1 = cast * %t1 to * This peephole eliminated 9 evil casts in the health benchmark, and completely turned the addList method around. :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1085 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/LevelRaise.cpp | 94 +++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp index 300224e3409..039bfd20d72 100644 --- a/lib/Transforms/LevelRaise.cpp +++ b/lib/Transforms/LevelRaise.cpp @@ -467,8 +467,12 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { Instruction *SrcI = dyn_cast(Src); // Nonnull if instr source const Type *DestTy = CI->getType(); - // Check for a cast of the same type as the destination! - if (DestTy == Src->getType()) { + // Peephole optimize the following instruction: + // %V2 = cast %V to + // + // Into: + // + if (DestTy == Src->getType()) { // Check for a cast to same type as src!! PRINT_PEEPHOLE1("cast-of-self-ty", CI); CI->replaceAllUsesWith(Src); if (!Src->hasName() && CI->hasName()) { @@ -479,7 +483,12 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { return true; } - // Check for a cast of cast, where no size information is lost... + // Peephole optimize the following instructions: + // %tmp = cast %V to + // %V = cast %tmp to ; Where ty & ty2 are same size + // + // Into: cast %V to + // if (SrcI) if (CastInst *CSrc = dyn_cast(SrcI)) if (isReinterpretingCast(CI) + isReinterpretingCast(CSrc) < 2) { @@ -505,6 +514,85 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { return true; } + // Check to see if we are casting from a structure pointer to a pointer to + // the first element of the structure... to avoid munching other peepholes, + // we only let this happen if there are no add uses of the cast. + // + // Peephole optimize the following instructions: + // %t1 = cast {<...>} * %StructPtr to * + // + // Into: %t2 = getelementptr {<...>} * %StructPtr, <0, 0, 0, ...> + // %t1 = cast * %t1 to * + // + if (const StructType *STy = getPointedToStruct(Src->getType())) + if (const PointerType *DestPTy = dyn_cast(DestTy)) { + + // Loop over uses of the cast, checking for add instructions. If an add + // exists, this is probably a part of a more complex GEP, so we don't + // want to mess around with the cast. + // + bool HasAddUse = false; + for (Value::use_iterator I = CI->use_begin(), E = CI->use_end(); + I != E; ++I) + if (isa(*I) && + cast(*I)->getOpcode() == Instruction::Add) { + HasAddUse = true; break; + } + + // If it doesn't have an add use, check to see if the dest type is + // losslessly convertable to one of the types in the start of the struct + // type. + // + if (!HasAddUse) { + const Type *DestPointedTy = DestPTy->getValueType(); + unsigned Depth = 1; + const StructType *CurSTy = STy; + const Type *ElTy = 0; + while (CurSTy) { + + // Check for a zero element struct type... if we have one, bail. + if (CurSTy->getElementTypes().size() == 0) break; + + // Grab the first element of the struct type, which must lie at + // offset zero in the struct. + // + ElTy = CurSTy->getElementTypes()[0]; + + // Did we find what we're looking for? + if (losslessCastableTypes(ElTy, DestPointedTy)) break; + + // Nope, go a level deeper. + ++Depth; + CurSTy = dyn_cast(ElTy); + ElTy = 0; + } + + // Did we find what we were looking for? If so, do the transformation + if (ElTy) { + PRINT_PEEPHOLE1("cast-for-first:in", CI); + + // Build the index vector, full of all zeros + vector Indices(Depth, + ConstPoolUInt::get(Type::UByteTy,0)); + + // Insert the new T cast instruction... stealing old T's name + GetElementPtrInst *GEP = new GetElementPtrInst(Src, Indices, + CI->getName()); + CI->setName(""); + BI = BB->getInstList().insert(BI, GEP)+1; + + // Make the old cast instruction reference the new GEP instead of + // the old src value. + // + CI->setOperand(0, GEP); + + PRINT_PEEPHOLE2("cast-for-first:out", GEP, CI); + return true; + } + } + } + + } else if (MallocInst *MI = dyn_cast(I)) { if (PeepholeMallocInst(BB, BI)) return true;