aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/LevelRaise.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-11-01 17:05:27 +0000
committerChris Lattner <sabre@nondot.org>2001-11-01 17:05:27 +0000
commite99c66b74fe04aeebeeb1b0c50ed0ea5ba45d371 (patch)
tree1f16028393b2a3b0a759a6b4f959fd5667c18e62 /lib/Transforms/LevelRaise.cpp
parent68b07b7c5de181d58b6833defccd6ebb79e689b9 (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.cpp94
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;