diff options
author | Chris Lattner <sabre@nondot.org> | 2001-11-01 17:05:27 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2001-11-01 17:05:27 +0000 |
commit | e99c66b74fe04aeebeeb1b0c50ed0ea5ba45d371 (patch) | |
tree | 1f16028393b2a3b0a759a6b4f959fd5667c18e62 /lib/Transforms/LevelRaise.cpp | |
parent | 68b07b7c5de181d58b6833defccd6ebb79e689b9 (diff) |
* Add comments for peepholes
* Implement new peephole:
// Peephole optimize the following instructions:
// %t1 = cast {<...>} * %StructPtr to <ty> *
//
// Into: %t2 = getelementptr {<...>} * %StructPtr, <0, 0, 0, ...>
// %t1 = cast <eltype> * %t1 to <ty> *
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
Diffstat (limited to 'lib/Transforms/LevelRaise.cpp')
-rw-r--r-- | lib/Transforms/LevelRaise.cpp | 94 |
1 files changed, 91 insertions, 3 deletions
diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp index 300224e340..039bfd20d7 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<Instruction>(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 <ty> %V to <ty> + // + // Into: <nothing> + // + 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 <ty> %V to <ty2> + // %V = cast <ty2> %tmp to <ty3> ; Where ty & ty2 are same size + // + // Into: cast <ty> %V to <ty3> + // if (SrcI) if (CastInst *CSrc = dyn_cast<CastInst>(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 <ty> * + // + // Into: %t2 = getelementptr {<...>} * %StructPtr, <0, 0, 0, ...> + // %t1 = cast <eltype> * %t1 to <ty> * + // + if (const StructType *STy = getPointedToStruct(Src->getType())) + if (const PointerType *DestPTy = dyn_cast<PointerType>(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<Instruction>(*I) && + cast<Instruction>(*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<StructType>(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<ConstPoolVal *> 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<MallocInst>(I)) { if (PeepholeMallocInst(BB, BI)) return true; |