X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FLevelRaise.cpp;h=a1ca7eb22daa01ba986b0246a1f0d4f3f1f7b228;hb=b461373fbcdc5909cc7331fa64791cd039de4bc8;hp=c3100347680a9e02e618b6f6c1c625e34fdf3115;hpb=7e70829632f82de15db187845666aaca6e04b792;p=oota-llvm.git diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp index c3100347680..a1ca7eb22da 100644 --- a/lib/Transforms/LevelRaise.cpp +++ b/lib/Transforms/LevelRaise.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/LevelChange.h" +#include "llvm/Transforms/RaisePointerReferences.h" #include "llvm/Transforms/Utils/Local.h" #include "TransformInternals.h" #include "llvm/iOther.h" @@ -14,16 +14,36 @@ #include "llvm/Pass.h" #include "llvm/ConstantHandling.h" #include "llvm/Analysis/Expressions.h" +#include "llvm/Analysis/Verifier.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "Support/STLExtras.h" #include "Support/StatisticReporter.h" +#include "Support/CommandLine.h" #include +using std::cerr; -static Statistic<> NumLoadStorePeepholes("raise\t\t- Number of load/store peepholes"); -static Statistic<> NumGEPInstFormed("raise\t\t- Number of other getelementptr's formed"); -static Statistic<> NumExprTreesConv("raise\t\t- Number of expression trees converted"); -static Statistic<> NumCastOfCast("raise\t\t- Number of cast-of-self removed"); -static Statistic<> NumDCEorCP("raise\t\t- Number of insts DCE'd or constprop'd"); +// StartInst - This enables the -raise-start-inst=foo option to cause the level +// raising pass to start at instruction "foo", which is immensely useful for +// debugging! +// +static cl::opt +StartInst("raise-start-inst", cl::Hidden, cl::value_desc("inst name"), + cl::desc("Start raise pass at the instruction with the specified name")); + +static Statistic<> +NumLoadStorePeepholes("raise\t\t- Number of load/store peepholes"); + +static Statistic<> +NumGEPInstFormed("raise\t\t- Number of other getelementptr's formed"); + +static Statistic<> +NumExprTreesConv("raise\t\t- Number of expression trees converted"); + +static Statistic<> +NumCastOfCast("raise\t\t- Number of cast-of-self removed"); + +static Statistic<> +NumDCEorCP("raise\t\t- Number of insts DCEd or constprop'd"); #define PRINT_PEEPHOLE(ID, NUM, I) \ @@ -67,7 +87,9 @@ static bool HandleCastToPointer(BasicBlock::iterator BI, for (Value::use_iterator I = CI.use_begin(), E = CI.use_end(); I != E; ++I) { if (BinaryOperator *BO = dyn_cast(*I)) { - if (BO->getOpcode() != Instruction::Add) + if (BO->getOpcode() != Instruction::Add || + // Avoid add sbyte* %X, %X cases... + BO->getOperand(0) == BO->getOperand(1)) return false; } else { return false; @@ -143,7 +165,7 @@ static bool PeepholeOptimizeAddCast(BasicBlock *BB, BasicBlock::iterator &BI, } // Only proceed if we have detected all of our conditions successfully... - if (!CompTy || !SrcPtr || !OffsetVal->getType()->isIntegral()) + if (!CompTy || !SrcPtr || !OffsetVal->getType()->isInteger()) return false; std::vector Indices; @@ -157,8 +179,7 @@ static bool PeepholeOptimizeAddCast(BasicBlock *BB, BasicBlock::iterator &BI, } GetElementPtrInst *GEP = new GetElementPtrInst(SrcPtr, Indices, - AddOp2->getName()); - BI = ++BB->getInstList().insert(BI, GEP); + AddOp2->getName(), BI); Instruction *NCI = new CastInst(GEP, AddOp1->getType()); ReplaceInstWithInst(BB->getInstList(), BI, NCI); @@ -210,14 +231,20 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { PRINT_PEEPHOLE3("CAST-SRC-EXPR-CONV:in ", Src, CI, BB->getParent()); DEBUG(cerr << "\nCONVERTING SRC EXPR TYPE:\n"); - ValueMapCache ValueMap; - Value *E = ConvertExpressionToType(Src, DestTy, ValueMap); - if (Constant *CPV = dyn_cast(E)) - CI->replaceAllUsesWith(CPV); + { // ValueMap must be destroyed before function verified! + ValueMapCache ValueMap; + Value *E = ConvertExpressionToType(Src, DestTy, ValueMap); + if (Constant *CPV = dyn_cast(E)) + CI->replaceAllUsesWith(CPV); + + PRINT_PEEPHOLE1("CAST-SRC-EXPR-CONV:out", E); + DEBUG(cerr << "DONE CONVERTING SRC EXPR TYPE: \n" << BB->getParent()); + } + + DEBUG(assert(verifyFunction(*BB->getParent()) == false && + "Function broken!")); BI = BB->begin(); // Rescan basic block. BI might be invalidated. - PRINT_PEEPHOLE1("CAST-SRC-EXPR-CONV:out", E); - DEBUG(cerr << "DONE CONVERTING SRC EXPR TYPE: \n" << BB->getParent()); ++NumExprTreesConv; return true; } @@ -226,16 +253,22 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { // source type of the cast... // ConvertedTypes.clear(); + ConvertedTypes[Src] = Src->getType(); // Make sure the source doesn't change type if (ValueConvertableToType(CI, Src->getType(), ConvertedTypes)) { PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", Src, CI, BB->getParent()); DEBUG(cerr << "\nCONVERTING EXPR TYPE:\n"); - ValueMapCache ValueMap; - ConvertValueToNewType(CI, Src, ValueMap); // This will delete CI! + { // ValueMap must be destroyed before function verified! + ValueMapCache ValueMap; + ConvertValueToNewType(CI, Src, ValueMap); // This will delete CI! + } - BI = BB->begin(); // Rescan basic block. BI might be invalidated. PRINT_PEEPHOLE1("CAST-DEST-EXPR-CONV:out", Src); DEBUG(cerr << "DONE CONVERTING EXPR TYPE: \n\n" << BB->getParent()); + + DEBUG(assert(verifyFunction(*BB->getParent()) == false && + "Function broken!")); + BI = BB->begin(); // Rescan basic block. BI might be invalidated. ++NumExprTreesConv; return true; } @@ -290,7 +323,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { // Build the index vector, full of all zeros std::vector Indices; - Indices.push_back(ConstantUInt::get(Type::UIntTy, 0)); + Indices.push_back(ConstantSInt::get(Type::LongTy, 0)); while (CurCTy && !isa(CurCTy)) { if (const StructType *CurSTy = dyn_cast(CurCTy)) { // Check for a zero element struct type... if we have one, bail. @@ -305,7 +338,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { } // Insert a zero to index through this type... - Indices.push_back(ConstantUInt::get(CurCTy->getIndexType(), 0)); + Indices.push_back(Constant::getNullValue(CurCTy->getIndexType())); // Did we find what we're looking for? if (ElTy->isLosslesslyConvertableTo(DestPointedTy)) break; @@ -320,11 +353,11 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { if (ElTy) { PRINT_PEEPHOLE1("cast-for-first:in", CI); + std::string Name = CI->getName(); CI->setName(""); + // 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); + Name, BI); // Make the old cast instruction reference the new GEP instead of // the old src value. @@ -359,15 +392,13 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType if (const PointerType *CSPT = dyn_cast(CastSrc->getType())) // convertable types? - if (Val->getType()->isLosslesslyConvertableTo(CSPT->getElementType()) && - !SI->hasIndices()) { // No subscripts yet! + if (Val->getType()->isLosslesslyConvertableTo(CSPT->getElementType())) { PRINT_PEEPHOLE3("st-src-cast:in ", Pointer, Val, SI); // Insert the new T cast instruction... stealing old T's name + std::string Name(CI->getName()); CI->setName(""); CastInst *NCI = new CastInst(Val, CSPT->getElementType(), - CI->getName()); - CI->setName(""); - BI = ++BB->getInstList().insert(BI, NCI); + Name, BI); // Replace the old store with a new one! ReplaceInstWithInst(BB->getInstList(), BI, @@ -399,16 +430,14 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType if (const PointerType *CSPT = dyn_cast(CastSrc->getType())) // convertable types? - if (PtrElType->isLosslesslyConvertableTo(CSPT->getElementType()) && - !LI->hasIndices()) { // No subscripts yet! + if (PtrElType->isLosslesslyConvertableTo(CSPT->getElementType())) { PRINT_PEEPHOLE2("load-src-cast:in ", Pointer, LI); // Create the new load instruction... loading the pre-casted value - LoadInst *NewLI = new LoadInst(CastSrc, LI->getName()); + LoadInst *NewLI = new LoadInst(CastSrc, LI->getName(), BI); // Insert the new T cast instruction... stealing old T's name CastInst *NCI = new CastInst(NewLI, LI->getType(), CI->getName()); - BI = ++BB->getInstList().insert(BI, NewLI); // Replace the old store with a new one! ReplaceInstWithInst(BB->getInstList(), BI, NCI); @@ -441,7 +470,7 @@ static bool DoRaisePass(Function &F) { if (dceInstruction(BI) || doConstantPropogation(BI)) { Changed = true; ++NumDCEorCP; - DEBUG(cerr << "***\t\t^^-- DeadCode Elinated!\n"); + DEBUG(cerr << "***\t\t^^-- Dead code eliminated!\n"); } else if (PeepholeOptimize(BB, BI)) { Changed = true; } else { @@ -464,6 +493,21 @@ static bool doRPR(Function &F) { // bool Changed = false, LocalChange; + + // If the StartInst option was specified, then Peephole optimize that + // instruction first if it occurs in this function. + // + if (!StartInst.empty()) { + for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) + for (BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI) + if (BI->getName() == StartInst) { + bool SavedDebug = DebugFlag; // Save the DEBUG() controlling flag. + DebugFlag = true; // Turn on DEBUG's + Changed |= PeepholeOptimize(BB, BI); + DebugFlag = SavedDebug; // Restore DebugFlag to previous state + } + } + do { DEBUG(cerr << "Looping: \n" << F); @@ -480,7 +524,9 @@ static bool doRPR(Function &F) { namespace { struct RaisePointerReferences : public FunctionPass { - const char *getPassName() const { return "Raise Pointer References"; } + + // FIXME: constructor should save and use target data here!! + RaisePointerReferences(const TargetData &TD) {} virtual bool runOnFunction(Function &F) { return doRPR(F); } @@ -490,8 +536,9 @@ namespace { }; } -Pass *createRaisePointerReferencesPass() { - return new RaisePointerReferences(); +Pass *createRaisePointerReferencesPass(const TargetData &TD) { + return new RaisePointerReferences(TD); } - +static RegisterOpt +X("raise", "Raise Pointer References", createRaisePointerReferencesPass);