From dedee7bf15cb5dca3bbca20b67ff5b6a47ce4605 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 1 Nov 2001 05:57:59 +0000 Subject: [PATCH] * Implement expression type conversion for constant values * Fix a problem setting a name on a constant value that died because no symbol table was passed in * Add some comments describing the passes * Implement a new peephole: // Peephole optimize the following instructions: // %t = cast * %P to * ;; If T1 is losslessly convertable to T2 // store %V, * %t // // Into: // %t = cast %V to // store %t2, * %P git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1080 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/LevelRaise.cpp | 87 ++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 11 deletions(-) diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp index db4e94e72e2..61610acae91 100644 --- a/lib/Transforms/LevelRaise.cpp +++ b/lib/Transforms/LevelRaise.cpp @@ -36,6 +36,7 @@ #include "llvm/iMemory.h" #include "llvm/ConstPoolVals.h" #include "llvm/Target/TargetData.h" +#include "llvm/Optimizations/ConstantHandling.h" #include #include @@ -70,8 +71,8 @@ const TargetData TD("LevelRaise: Should be GCC though!"); // another without gaining or losing precision, or altering the bits in any way. // static bool losslessCastableTypes(const Type *T1, const Type *T2) { - assert(T1->isPrimitiveType() || isa(T1)); - assert(T2->isPrimitiveType() || isa(T2)); + if (!T1->isPrimitiveType() && !isa(T1)) return false; + if (!T2->isPrimitiveType() && !isa(T2)) return false; if (T1->getPrimitiveID() == T2->getPrimitiveID()) return true; // Handles identity cast, and cast of differing pointer types @@ -195,7 +196,16 @@ static void ReplaceInstWithInst(BasicBlock::InstListType &BIL, // ExpressionConvertableToType - Return true if it is possible static bool ExpressionConvertableToType(Value *V, const Type *Ty) { Instruction *I = dyn_cast(V); - if (I == 0) return false; // Noninstructions can't convert + if (I == 0) { + // It's not an instruction, check to see if it's a constant... all constants + // can be converted to an equivalent value (except pointers, they can't be + // const prop'd in general). + // + if (isa(V) && + !isa(V->getType()) && !isa(Ty)) return true; + + return false; // Otherwise, we can't convert! + } if (I->getType() == Ty) return false; // Expression already correct type! switch (I->getOpcode()) { @@ -216,9 +226,20 @@ static bool ExpressionConvertableToType(Value *V, const Type *Ty) { } -static Instruction *ConvertExpressionToType(Value *V, const Type *Ty) { - Instruction *I = cast(V); - assert(ExpressionConvertableToType(I, Ty) && "Inst is not convertable!"); +static Value *ConvertExpressionToType(Value *V, const Type *Ty) { + assert(ExpressionConvertableToType(V, Ty) && "Value is not convertable!"); + Instruction *I = dyn_cast(V); + if (I == 0) + if (ConstPoolVal *CPV = cast(V)) { + // Constants are converted by constant folding the cast that is required. + // We assume here that all casts are implemented for constant prop. + Value *Result = opt::ConstantFoldCastInstruction(CPV, Ty); + if (!Result) cerr << "Couldn't fold " << CPV << " to " << Ty << endl; + assert(Result && "ConstantFoldCastInstruction Failed!!!"); + return Result; + } + + BasicBlock *BB = I->getParent(); BasicBlock::InstListType &BIL = BB->getInstList(); string Name = I->getName(); if (!Name.empty()) I->setName(""); @@ -438,6 +459,7 @@ static bool PeepholeMallocInst(BasicBlock *BB, BasicBlock::iterator &BI) { static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { Instruction *I = *BI; + // TODO: replace this with a DCE call if (I->use_size() == 0 && I->getType() != Type::VoidTy) return false; if (CastInst *CI = dyn_cast(I)) { @@ -451,7 +473,8 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { CI->replaceAllUsesWith(Src); if (!Src->hasName() && CI->hasName()) { string Name = CI->getName(); - CI->setName(""); Src->setName(Name); + CI->setName(""); Src->setName(Name, + BB->getParent()->getSymbolTable()); } return true; } @@ -473,10 +496,10 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { // Check to see if it's a cast of an instruction that does not depend on the // specific type of the operands to do it's job. - if (SrcI && !isReinterpretingCast(CI) && - ExpressionConvertableToType(SrcI, DestTy)) { - PRINT_PEEPHOLE2("EXPR-CONV:in ", CI, SrcI); - CI->setOperand(0, ConvertExpressionToType(SrcI, DestTy)); + if (!isReinterpretingCast(CI) && + ExpressionConvertableToType(Src, DestTy)) { + PRINT_PEEPHOLE2("EXPR-CONV:in ", CI, Src); + CI->setOperand(0, ConvertExpressionToType(Src, DestTy)); BI = BB->begin(); // Rescan basic block. BI might be invalidated. PRINT_PEEPHOLE2("EXPR-CONV:out", CI, CI->getOperand(0)); return true; @@ -489,6 +512,12 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { Value *Val = SI->getOperand(0); Value *Pointer = SI->getPtrOperand(); + // Peephole optimize the following instructions: + // %t1 = getelementptr {<...>} * %StructPtr, + // store %v, * %t1 + // + // Into: store %v, {<...>} * %StructPtr, + // if (GetElementPtrInst *GEP = dyn_cast(Pointer)) { PRINT_PEEPHOLE2("gep-store:in", GEP, SI); ReplaceInstWithInst(BB->getInstList(), BI, @@ -497,10 +526,46 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { PRINT_PEEPHOLE1("gep-store:out", SI); return true; } + + // Peephole optimize the following instructions: + // %t = cast * %P to * ;; If T1 is losslessly convertable to T2 + // store %V, * %t + // + // Into: + // %t = cast %V to + // store %t2, * %P + // + if (CastInst *CI = dyn_cast(Pointer)) + if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType + if (PointerType *CSPT = dyn_cast(CastSrc->getType())) + if (losslessCastableTypes(Val->getType(), // convertable types! + CSPT->getValueType()) && + !SI->hasIndices()) { // No subscripts yet! + PRINT_PEEPHOLE3("st-src-cast:in ", Pointer, Val, SI); + + // Insert the new T cast instruction... stealing old T's name + CastInst *NCI = new CastInst(Val, CSPT->getValueType(), + CI->getName()); + CI->setName(""); + BI = BB->getInstList().insert(BI, NCI)+1; + + // Replace the old store with a new one! + ReplaceInstWithInst(BB->getInstList(), BI, + SI = new StoreInst(NCI, CastSrc)); + PRINT_PEEPHOLE3("st-src-cast:out", NCI, CastSrc, SI); + return true; + } + } else if (LoadInst *LI = dyn_cast(I)) { Value *Pointer = LI->getPtrOperand(); + // Peephole optimize the following instructions: + // %t1 = getelementptr {<...>} * %StructPtr, + // %V = load * %t1 + // + // Into: load {<...>} * %StructPtr, + // if (GetElementPtrInst *GEP = dyn_cast(Pointer)) { PRINT_PEEPHOLE2("gep-load:in", GEP, LI); ReplaceInstWithInst(BB->getInstList(), BI,