Add new optional getPassName() virtual function that a Pass can override
[oota-llvm.git] / lib / Transforms / LevelRaise.cpp
index e47eb906428a660bf694100b9fa2caeb5c2f1a6d..f9f9abeace97d5a19d81be3e78fb5fee93ae554c 100644 (file)
@@ -8,24 +8,23 @@
 
 #include "llvm/Transforms/LevelChange.h"
 #include "TransformInternals.h"
-#include "llvm/Method.h"
+#include "llvm/Function.h"
 #include "llvm/iOther.h"
 #include "llvm/iMemory.h"
-#include "llvm/ConstantVals.h"
-#include "llvm/Optimizations/ConstantHandling.h"
-#include "llvm/Optimizations/DCE.h"
-#include "llvm/Optimizations/ConstantProp.h"
+#include "llvm/Constants.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 "Support/STLExtras.h"
 #include <algorithm>
 
-#include "llvm/Assembly/Writer.h"
-
 //#define DEBUG_PEEPHOLE_INSTS 1
 
 #ifdef DEBUG_PEEPHOLE_INSTS
 #define PRINT_PEEPHOLE(ID, NUM, I)            \
-  cerr << "Inst P/H " << ID << "[" << NUM << "] " << I;
+  std::cerr << "Inst P/H " << ID << "[" << NUM << "] " << I;
 #else
 #define PRINT_PEEPHOLE(ID, NUM, I)
 #endif
@@ -61,6 +60,7 @@ static inline bool isReinterpretingCast(const CastInst *CI) {
 static bool HandleCastToPointer(BasicBlock::iterator BI,
                                 const PointerType *DestPTy) {
   CastInst *CI = cast<CastInst>(*BI);
+  if (CI->use_empty()) return false;
 
   // Scan all of the uses, looking for any uses that are not add
   // instructions.  If we have non-adds, do not make this transformation.
@@ -75,7 +75,7 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
     }
   }
 
-  vector<Value*> Indices;
+  std::vector<Value*> Indices;
   Value *Src = CI->getOperand(0);
   const Type *Result = ConvertableToGEP(DestPTy, Src, Indices, &BI);
   if (Result == 0) return false;  // Not convertable...
@@ -84,25 +84,37 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
 
   // If we have a getelementptr capability... transform all of the 
   // add instruction uses into getelementptr's.
-  for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end();
-       UI != E; ++UI) {
-    Instruction *I = cast<Instruction>(*UI);
+  while (!CI->use_empty()) {
+    BinaryOperator *I = cast<BinaryOperator>(*CI->use_begin());
     assert(I->getOpcode() == Instruction::Add && I->getNumOperands() == 2 &&
            "Use is not a valid add instruction!");
     
     // Get the value added to the cast result pointer...
     Value *OtherPtr = I->getOperand((I->getOperand(0) == CI) ? 1 : 0);
 
-    BasicBlock *BB = I->getParent();
-    BasicBlock::iterator AddIt = find(BB->getInstList().begin(),
-                                      BB->getInstList().end(), I);
+    Instruction *GEP = new GetElementPtrInst(OtherPtr, Indices, I->getName());
+    PRINT_PEEPHOLE1("cast-add-to-gep:i", I);
 
-    GetElementPtrInst *GEP = new GetElementPtrInst(OtherPtr, Indices);
+    if (GEP->getType() == I->getType()) {
+      // Replace the old add instruction with the shiny new GEP inst
+      ReplaceInstWithInst(I, GEP);
+    } else {
+      // If the type produced by the gep instruction differs from the original
+      // add instruction type, insert a cast now.
+      //
+
+      // Insert the GEP instruction before the old add instruction... and get an
+      // iterator to point at the add instruction...
+      BasicBlock::iterator GEPI = InsertInstBeforeInst(GEP, I)+1;
+
+      PRINT_PEEPHOLE1("cast-add-to-gep:o", GEP);
+      CastInst *CI = new CastInst(GEP, I->getType());
+      GEP = CI;
+
+      // Replace the old add instruction with the shiny new GEP inst
+      ReplaceInstWithInst(I->getParent()->getInstList(), GEPI, GEP);
+    }
 
-    PRINT_PEEPHOLE1("cast-add-to-gep:i", I);
-    
-    // Replace the old add instruction with the shiny new GEP inst
-    ReplaceInstWithInst(BB->getInstList(), AddIt, GEP);
     PRINT_PEEPHOLE1("cast-add-to-gep:o", GEP);
   }
   return true;
@@ -137,7 +149,7 @@ static bool PeepholeOptimizeAddCast(BasicBlock *BB, BasicBlock::iterator &BI,
   if (!CompTy || !SrcPtr || !OffsetVal->getType()->isIntegral())
     return false;
 
-  vector<Value*> Indices;
+  std::vector<Value*> Indices;
   if (!ConvertableToGEP(SrcPtr->getType(), OffsetVal, Indices, &BI))
     return false;  // Not convertable... perhaps next time
 
@@ -174,7 +186,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
       PRINT_PEEPHOLE1("cast-of-self-ty", CI);
       CI->replaceAllUsesWith(Src);
       if (!Src->hasName() && CI->hasName()) {
-        string Name = CI->getName();
+        std::string Name = CI->getName();
         CI->setName("");
         Src->setName(Name, BB->getParent()->getSymbolTable());
       }
@@ -299,7 +311,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
           const Type *ElTy = 0;
 
           // Build the index vector, full of all zeros
-          vector<Value*> Indices;
+          std::vector<Value*> Indices;
           Indices.push_back(ConstantUInt::get(Type::UIntTy, 0));
           while (CurCTy && !isa<PointerType>(CurCTy)) {
             if (const StructType *CurSTy = dyn_cast<StructType>(CurCTy)) {
@@ -403,9 +415,9 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
 
 
 
-static bool DoRaisePass(Method *M) {
+static bool DoRaisePass(Function *F) {
   bool Changed = false;
-  for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) {
+  for (Function::iterator MI = F->begin(), ME = F->end(); MI != ME; ++MI) {
     BasicBlock *BB = *MI;
     BasicBlock::InstListType &BIL = BB->getInstList();
 
@@ -413,11 +425,10 @@ static bool DoRaisePass(Method *M) {
 #if DEBUG_PEEPHOLE_INSTS
       cerr << "Processing: " << *BI;
 #endif
-      if (opt::DeadCodeElimination::dceInstruction(BIL, BI) ||
-         opt::ConstantPropogation::doConstantPropogation(BB, BI)) {
+      if (dceInstruction(BIL, BI) || doConstantPropogation(BB, BI)) {
         Changed = true; 
 #ifdef DEBUG_PEEPHOLE_INSTS
-        cerr << "DeadCode Elinated!\n";
+        cerr << "***\t\t^^-- DeadCode Elinated!\n";
 #endif
       } else if (PeepholeOptimize(BB, BI))
         Changed = true;
@@ -429,16 +440,12 @@ static bool DoRaisePass(Method *M) {
 }
 
 
-
-
-// RaisePointerReferences::doit - Raise a method representation to a higher
+// RaisePointerReferences::doit - Raise a function representation to a higher
 // level.
 //
-bool RaisePointerReferences::doit(Method *M) {
-  if (M->isExternal()) return false;
-
+static bool doRPR(Function *F) {
 #ifdef DEBUG_PEEPHOLE_INSTS
-  cerr << "\n\n\nStarting to work on Method '" << M->getName() << "'\n";
+  cerr << "\n\n\nStarting to work on Function '" << F->getName() << "'\n";
 #endif
 
   // Insert casts for all incoming pointer pointer values that are treated as
@@ -448,16 +455,34 @@ bool RaisePointerReferences::doit(Method *M) {
   
   do {
 #ifdef DEBUG_PEEPHOLE_INSTS
-    cerr << "Looping: \n" << M;
+    cerr << "Looping: \n" << F;
 #endif
 
-    // Iterate over the method, refining it, until it converges on a stable
+    // Iterate over the function, refining it, until it converges on a stable
     // state
     LocalChange = false;
-    while (DoRaisePass(M)) LocalChange = true;
+    while (DoRaisePass(F)) LocalChange = true;
     Changed |= LocalChange;
 
   } while (LocalChange);
 
   return Changed;
 }
+
+namespace {
+  struct RaisePointerReferences : public FunctionPass {
+    const char *getPassName() const { return "Raise Pointer References"; }
+
+    virtual bool runOnFunction(Function *F) { return doRPR(F); }
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.preservesCFG();
+    }
+  };
+}
+
+Pass *createRaisePointerReferencesPass() {
+  return new RaisePointerReferences();
+}
+
+