Convert transforms over to standardize debugging output on -debug option
[oota-llvm.git] / lib / Transforms / LevelRaise.cpp
index cc684b5f150fa7f09d2169855a36f79dc2ac6909..b76e8baa4b2295787c4748679f5d636ee569db6c 100644 (file)
@@ -7,25 +7,27 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/LevelChange.h"
+#include "llvm/Transforms/Utils/Local.h"
 #include "TransformInternals.h"
 #include "llvm/iOther.h"
 #include "llvm/iMemory.h"
 #include "llvm/Pass.h"
 #include "llvm/ConstantHandling.h"
-#include "llvm/Transforms/Scalar/DCE.h"
-#include "llvm/Transforms/Scalar/ConstantProp.h"
 #include "llvm/Analysis/Expressions.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "Support/STLExtras.h"
+#include "Support/StatisticReporter.h"
 #include <algorithm>
 
-//#define DEBUG_PEEPHOLE_INSTS 1
+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");
+
 
-#ifdef DEBUG_PEEPHOLE_INSTS
 #define PRINT_PEEPHOLE(ID, NUM, I)            \
-  std::cerr << "Inst P/H " << ID << "[" << NUM << "] " << I;
-#else
-#define PRINT_PEEPHOLE(ID, NUM, I)
-#endif
+  DEBUG(std::cerr << "Inst P/H " << ID << "[" << NUM << "] " << I)
 
 #define PRINT_PEEPHOLE1(ID, I1) do { PRINT_PEEPHOLE(ID, 0, I1); } while (0)
 #define PRINT_PEEPHOLE2(ID, I1, I2) \
@@ -187,6 +189,13 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
         CI->setName("");
         Src->setName(Name, BB->getParent()->getSymbolTable());
       }
+
+      // DCE the instruction now, to avoid having the iterative version of DCE
+      // have to worry about it.
+      //
+      delete BB->getInstList().remove(BI);
+
+      ++NumCastOfCast;
       return true;
     }
 
@@ -202,9 +211,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
       if (ExpressionConvertableToType(Src, DestTy, ConvertedTypes)) {
         PRINT_PEEPHOLE3("CAST-SRC-EXPR-CONV:in ", Src, CI, BB->getParent());
           
-#ifdef DEBUG_PEEPHOLE_INSTS
-        cerr << "\nCONVERTING SRC EXPR TYPE:\n";
-#endif
+        DEBUG(cerr << "\nCONVERTING SRC EXPR TYPE:\n");
         ValueMapCache ValueMap;
         Value *E = ConvertExpressionToType(Src, DestTy, ValueMap);
         if (Constant *CPV = dyn_cast<Constant>(E))
@@ -212,9 +219,8 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
 
         BI = BB->begin();  // Rescan basic block.  BI might be invalidated.
         PRINT_PEEPHOLE1("CAST-SRC-EXPR-CONV:out", E);
-#ifdef DEBUG_PEEPHOLE_INSTS
-        cerr << "DONE CONVERTING SRC EXPR TYPE: \n" << BB->getParent();
-#endif
+        DEBUG(cerr << "DONE CONVERTING SRC EXPR TYPE: \n" << BB->getParent());
+        ++NumExprTreesConv;
         return true;
       }
 
@@ -225,17 +231,14 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
       if (ValueConvertableToType(CI, Src->getType(), ConvertedTypes)) {
         PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", Src, CI, BB->getParent());
 
-#ifdef DEBUG_PEEPHOLE_INSTS
-        cerr << "\nCONVERTING EXPR TYPE:\n";
-#endif
+        DEBUG(cerr << "\nCONVERTING EXPR TYPE:\n");
         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);
-#ifdef DEBUG_PEEPHOLE_INSTS
-        cerr << "DONE CONVERTING EXPR TYPE: \n\n" << BB->getParent();
-#endif
+        DEBUG(cerr << "DONE CONVERTING EXPR TYPE: \n\n" << BB->getParent());
+        ++NumExprTreesConv;
         return true;
       }
     }
@@ -247,6 +250,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
     if (const PointerType *DestPTy = dyn_cast<PointerType>(DestTy)) {
       if (HandleCastToPointer(BI, DestPTy)) {
         BI = BB->begin();  // Rescan basic block.  BI might be invalidated.
+        ++NumGEPInstFormed;
         return true;
       }
     }
@@ -261,7 +265,6 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
     // Into: %t2 = getelementptr {<...>} * %StructPtr, <0, 0, 0, ...>
     //       %t1 = cast <eltype> * %t1 to <ty> *
     //
-#if 1
     if (const CompositeType *CTy = getPointedToComposite(Src->getType()))
       if (const PointerType *DestPTy = dyn_cast<PointerType>(DestTy)) {
 
@@ -331,13 +334,12 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
             CI->setOperand(0, GEP);
             
             PRINT_PEEPHOLE2("cast-for-first:out", GEP, CI);
+            ++NumGEPInstFormed;
             return true;
           }
         }
       }
-#endif
 
-#if 1
   } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
     Value *Val     = SI->getOperand(0);
     Value *Pointer = SI->getPointerOperand();
@@ -373,6 +375,47 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
             ReplaceInstWithInst(BB->getInstList(), BI,
                                 SI = new StoreInst(NCI, CastSrc));
             PRINT_PEEPHOLE3("st-src-cast:out", NCI, CastSrc, SI);
+            ++NumLoadStorePeepholes;
+            return true;
+          }
+
+  } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
+    Value *Pointer = LI->getOperand(0);
+    const Type *PtrElType =
+      cast<PointerType>(Pointer->getType())->getElementType();
+    
+    // Peephole optimize the following instructions:
+    // %Val = cast <T1>* to <T2>*    ;; If T1 is losslessly convertable to T2
+    // %t = load <T2>* %P
+    //
+    // Into: 
+    // %t = load <T1>* %P
+    // %Val = cast <T1> to <T2>
+    //
+    // Note: This is not taken care of by expr conversion because there might
+    // not be a cast available for the store to convert the incoming value of.
+    // This code is basically here to make sure that pointers don't have casts
+    // if possible.
+    //
+    if (CastInst *CI = dyn_cast<CastInst>(Pointer))
+      if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
+        if (PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
+          // convertable types?
+          if (PtrElType->isLosslesslyConvertableTo(CSPT->getElementType()) &&
+              !LI->hasIndices()) {      // No subscripts yet!
+            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());
+            
+            // 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)+1;
+
+            // Replace the old store with a new one!
+            ReplaceInstWithInst(BB->getInstList(), BI, NCI);
+            PRINT_PEEPHOLE3("load-src-cast:out", NCI, CastSrc, NewLI);
+            ++NumLoadStorePeepholes;
             return true;
           }
 
@@ -380,10 +423,10 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
              isa<CastInst>(I->getOperand(1))) {
 
     if (PeepholeOptimizeAddCast(BB, BI, I->getOperand(0),
-                                cast<CastInst>(I->getOperand(1))))
+                                cast<CastInst>(I->getOperand(1)))) {
+      ++NumGEPInstFormed;
       return true;
-
-#endif
+    }
   }
 
   return false;
@@ -399,14 +442,11 @@ static bool DoRaisePass(Function *F) {
     BasicBlock::InstListType &BIL = BB->getInstList();
 
     for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
-#if DEBUG_PEEPHOLE_INSTS
-      cerr << "Processing: " << *BI;
-#endif
+      DEBUG(cerr << "Processing: " << *BI);
       if (dceInstruction(BIL, BI) || doConstantPropogation(BB, BI)) {
         Changed = true; 
-#ifdef DEBUG_PEEPHOLE_INSTS
-        cerr << "***\t\t^^-- DeadCode Elinated!\n";
-#endif
+        ++NumDCEorCP;
+        DEBUG(cerr << "***\t\t^^-- DeadCode Elinated!\n");
       } else if (PeepholeOptimize(BB, BI))
         Changed = true;
       else
@@ -421,9 +461,7 @@ static bool DoRaisePass(Function *F) {
 // level.
 //
 static bool doRPR(Function *F) {
-#ifdef DEBUG_PEEPHOLE_INSTS
-  cerr << "\n\n\nStarting to work on Function '" << F->getName() << "'\n";
-#endif
+  DEBUG(cerr << "\n\n\nStarting to work on Function '" << F->getName()<< "'\n");
 
   // Insert casts for all incoming pointer pointer values that are treated as
   // arrays...
@@ -431,9 +469,7 @@ static bool doRPR(Function *F) {
   bool Changed = false, LocalChange;
   
   do {
-#ifdef DEBUG_PEEPHOLE_INSTS
-    cerr << "Looping: \n" << F;
-#endif
+    DEBUG(cerr << "Looping: \n" << F);
 
     // Iterate over the function, refining it, until it converges on a stable
     // state