Author: evancheng Date: Wed Dec 5 17:58:20 2007 New Revision: 44643 URL: http://llvm.org/viewvc/llvm-project?rev=44643&view=rev Log: If both result of the {s|z}xt and its source are live out, rewrite all uses of the source with result of extension.
Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=44643&r1=44642&r2=44643&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Dec 5 17:58:20 2007 @@ -28,11 +28,17 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" -#include "llvm/Support/Debug.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/GetElementPtrTypeIterator.h" using namespace llvm; +namespace { + cl::opt<bool> OptExtUses("optimize-ext-uses", + cl::init(false), cl::Hidden); +} + namespace { class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass { /// TLI - Keep a pointer of a TargetLowering to consult for determining @@ -52,6 +58,7 @@ bool OptimizeLoadStoreInst(Instruction *I, Value *Addr, const Type *AccessTy, DenseMap<Value*,Value*> &SunkAddrs); + bool OptimizeExtUses(Instruction *I); }; } @@ -913,6 +920,61 @@ return true; } +bool CodeGenPrepare::OptimizeExtUses(Instruction *I) { + BasicBlock *DefBB = I->getParent(); + + // If both result of the {s|z}xt and its source are live out, rewrite all + // other uses of the source with result of extension. + Value *Src = I->getOperand(0); + if (Src->hasOneUse()) + return false; + + bool DefIsLiveOut = false; + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) { + Instruction *User = cast<Instruction>(*UI); + + // Figure out which BB this ext is used in. + BasicBlock *UserBB = User->getParent(); + if (UserBB == DefBB) continue; + DefIsLiveOut = true; + break; + } + if (!DefIsLiveOut) + return false; + + // InsertedTruncs - Only insert one trunc in each block once. + DenseMap<BasicBlock*, Instruction*> InsertedTruncs; + + bool MadeChange = false; + for (Value::use_iterator UI = Src->use_begin(), E = Src->use_end(); + UI != E; ++UI) { + Use &TheUse = UI.getUse(); + Instruction *User = cast<Instruction>(*UI); + + // Figure out which BB this ext is used in. + BasicBlock *UserBB = User->getParent(); + if (UserBB == DefBB) continue; + + // Both src and def are live in this block. Rewrite the use. + Instruction *&InsertedTrunc = InsertedTruncs[UserBB]; + + if (!InsertedTrunc) { + BasicBlock::iterator InsertPt = UserBB->begin(); + while (isa<PHINode>(InsertPt)) ++InsertPt; + + InsertedTrunc = new TruncInst(I, Src->getType(), "", InsertPt); + } + + // Replace a use of the {s|z}ext source with a use of the result. + TheUse = InsertedTrunc; + + MadeChange = true; + } + + return MadeChange; +} + // In this pass we look for GEP and cast instructions that are used // across basic blocks and rewrite them to improve basic-block-at-a-time // selection. @@ -948,8 +1010,14 @@ if (isa<Constant>(CI->getOperand(0))) continue; - if (TLI) - MadeChange |= OptimizeNoopCopyExpression(CI, *TLI); + bool Change = false; + if (TLI) { + Change = OptimizeNoopCopyExpression(CI, *TLI); + MadeChange |= Change; + } + + if (OptExtUses && !Change && (isa<ZExtInst>(I) || isa<SExtInst>(I))) + MadeChange |= OptimizeExtUses(I); } else if (CmpInst *CI = dyn_cast<CmpInst>(I)) { MadeChange |= OptimizeCmpExpression(CI); } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) { _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits