Add new transformation: // (~A | ~B) == (~(A & B))
[oota-llvm.git] / lib / Transforms / LevelRaise.cpp
index fd32251bea802f164c1c6a961ce3a72c3c6543d9..952082320635046f6a4bb87acccaecea81f43082 100644 (file)
@@ -17,7 +17,7 @@
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "Support/STLExtras.h"
-#include "Support/StatisticReporter.h"
+#include "Support/Statistic.h"
 #include "Support/CommandLine.h"
 #include <algorithm>
 using std::cerr;
@@ -31,19 +31,22 @@ 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");
+NumLoadStorePeepholes("raise", "Number of load/store peepholes");
 
 static Statistic<> 
-NumGEPInstFormed("raise\t\t- Number of other getelementptr's formed");
+NumGEPInstFormed("raise", "Number of other getelementptr's formed");
 
 static Statistic<>
-NumExprTreesConv("raise\t\t- Number of expression trees converted");
+NumExprTreesConv("raise", "Number of expression trees converted");
 
 static Statistic<>
-NumCastOfCast("raise\t\t- Number of cast-of-self removed");
+NumCastOfCast("raise", "Number of cast-of-self removed");
 
 static Statistic<>
-NumDCEorCP("raise\t\t- Number of insts DCEd or constprop'd");
+NumDCEorCP("raise", "Number of insts DCEd or constprop'd");
+
+static Statistic<>
+NumVarargCallChanges("raise", "Number of vararg call peepholes");
 
 
 #define PRINT_PEEPHOLE(ID, NUM, I)            \
@@ -155,7 +158,7 @@ static bool PeepholeOptimizeAddCast(BasicBlock *BB, BasicBlock::iterator &BI,
                                     Value *AddOp1, CastInst *AddOp2) {
   const CompositeType *CompTy;
   Value *OffsetVal = AddOp2->getOperand(0);
-  Value *SrcPtr;  // Of type pointer to struct...
+  Value *SrcPtr = 0;  // Of type pointer to struct...
 
   if ((CompTy = getPointedToComposite(AddOp1->getType()))) {
     SrcPtr = AddOp1;                      // Handle the first case...
@@ -206,7 +209,7 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
       if (!Src->hasName() && CI->hasName()) {
         std::string Name = CI->getName();
         CI->setName("");
-        Src->setName(Name, BB->getParent()->getSymbolTable());
+        Src->setName(Name, &BB->getParent()->getSymbolTable());
       }
 
       // DCE the instruction now, to avoid having the iterative version of DCE
@@ -253,7 +256,8 @@ 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
+      // Make sure the source doesn't change type
+      ConvertedTypes[Src] = Src->getType();
       if (ValueConvertableToType(CI, Src->getType(), ConvertedTypes)) {
         PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", Src, CI, BB->getParent());
 
@@ -454,6 +458,40 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
       ++NumGEPInstFormed;
       return true;
     }
+  } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
+    // If we have a call with all varargs arguments, convert the call to use the
+    // actual argument types present...
+    //
+    const PointerType *PTy = cast<PointerType>(CI->getCalledValue()->getType());
+    const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+
+    // Is the call to a vararg variable with no real parameters?
+    if (FTy->isVarArg() && FTy->getNumParams() == 0) {
+      // If so, insert a new cast instruction, casting it to a function type
+      // that matches the current arguments...
+      //
+      std::vector<const Type *> Params;  // Parameter types...
+      for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
+        Params.push_back(CI->getOperand(i)->getType());
+
+      FunctionType *NewFT = FunctionType::get(FTy->getReturnType(),
+                                              Params, false);
+      PointerType *NewPFunTy = PointerType::get(NewFT);
+
+      // Create a new cast, inserting it right before the function call...
+      CastInst *NewCast = new CastInst(CI->getCalledValue(), NewPFunTy,
+                                       CI->getCalledValue()->getName(), CI);
+
+      // Create a new call instruction...
+      CallInst *NewCall = new CallInst(NewCast,
+                           std::vector<Value*>(CI->op_begin()+1, CI->op_end()));
+      ++BI;
+      ReplaceInstWithInst(CI, NewCall);
+      
+      ++NumVarargCallChanges;
+      return true;
+    }
+
   }
 
   return false;
@@ -470,7 +508,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 {
@@ -531,7 +569,7 @@ namespace {
     virtual bool runOnFunction(Function &F) { return doRPR(F); }
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      AU.preservesCFG();
+      AU.setPreservesCFG();
     }
   };
 }