Remove some redundant checks, add a couple of new ones. This allows us to
[oota-llvm.git] / lib / Target / CBackend / CBackend.cpp
index acb7736e45f3d5190a89cadf7cc561cd4fe7150b..2e3e9a9edd169cdb33708f8afc5571d6becbc517 100644 (file)
@@ -33,6 +33,7 @@
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Config/config.h"
 #include <algorithm>
@@ -227,20 +228,19 @@ bool CBackendNameAllUsedStructs::runOnModule(Module &M) {
   std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes();
   
   // Loop over the module symbol table, removing types from UT that are
-  // already named, and removing names for structure types that are not used.
+  // already named, and removing names for types that are not used.
   //
   SymbolTable &MST = M.getSymbolTable();
   for (SymbolTable::type_iterator TI = MST.type_begin(), TE = MST.type_end();
        TI != TE; ) {
     SymbolTable::type_iterator I = TI++;
-    if (const StructType *STy = dyn_cast<StructType>(I->second)) {
-      // If this is not used, remove it from the symbol table.
-      std::set<const Type *>::iterator UTI = UT.find(STy);
-      if (UTI == UT.end())
-        MST.remove(I);
-      else
-        UT.erase(UTI);
-    }
+
+    // If this is not used, remove it from the symbol table.
+    std::set<const Type *>::iterator UTI = UT.find(I->second);
+    if (UTI == UT.end())
+      MST.remove(I);
+    else
+      UT.erase(UTI);    // Only keep one name for this type.
   }
 
   // UT now contains types that are not named.  Loop over it, naming
@@ -807,6 +807,7 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
       << "#define LLVM_NANSF(NanStr) __builtin_nansf(NanStr) /* Float */\n"
       << "#define LLVM_INF           __builtin_inf()         /* Double */\n"
       << "#define LLVM_INFF          __builtin_inff()        /* Float */\n"
+      << "#define LLVM_PREFETCH(addr,rw,locality)          __builtin_prefetch(addr,rw,locality)\n"
       << "#else\n"
       << "#define LLVM_NAN(NanStr)   ((double)0.0)           /* Double */\n"
       << "#define LLVM_NANF(NanStr)  0.0F                    /* Float */\n"
@@ -814,6 +815,7 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
       << "#define LLVM_NANSF(NanStr) 0.0F                    /* Float */\n"
       << "#define LLVM_INF           ((double)0.0)           /* Double */\n"
       << "#define LLVM_INFF          0.0F                    /* Float */\n"
+      << "#define LLVM_PREFETCH(addr,rw,locality)          \n"
       << "#endif\n";
 }
 
@@ -850,9 +852,9 @@ bool CWriter::doInitialization(Module &M) {
   printModuleTypes(M.getSymbolTable());
 
   // Global variable declarations...
-  if (!M.gempty()) {
+  if (!M.global_empty()) {
     Out << "\n/* External Global Variable Declarations */\n";
-    for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
+    for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
       if (I->hasExternalLinkage()) {
         Out << "extern ";
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
@@ -877,9 +879,9 @@ bool CWriter::doInitialization(Module &M) {
   }
 
   // Output the global variable declarations
-  if (!M.gempty()) {
+  if (!M.global_empty()) {
     Out << "\n\n/* Global Variable Declarations */\n";
-    for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+    for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
       if (!I->isExternal()) {
         if (I->hasInternalLinkage())
           Out << "static ";
@@ -896,9 +898,9 @@ bool CWriter::doInitialization(Module &M) {
   }
 
   // Output the global variable definitions and contents...
-  if (!M.gempty()) {
+  if (!M.global_empty()) {
     Out << "\n\n/* Global Variable Definitions and Initialization */\n";
-    for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+    for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
       if (!I->isExternal()) {
         if (I->hasInternalLinkage())
           Out << "static ";
@@ -988,13 +990,12 @@ void CWriter::printFloatingPointConstants(Function &F) {
 /// type name is found, emit it's declaration...
 ///
 void CWriter::printModuleTypes(const SymbolTable &ST) {
-  // If there are no type names, exit early.
-  if ( ! ST.hasTypes() )
-    return;
-
-  // We are only interested in the type plane of the symbol table...
+  // We are only interested in the type plane of the symbol table.
   SymbolTable::type_const_iterator I   = ST.type_begin();
   SymbolTable::type_const_iterator End = ST.type_end();
+
+  // If there are no type names, exit early.
+  if (I == End) return;
   
   // Print out forward declarations for structure types before anything else!
   Out << "/* Structure forward decls */\n";
@@ -1075,12 +1076,12 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   FunctionInnards << Mang->getValueName(F) << '(';
     
   if (!F->isExternal()) {
-    if (!F->aempty()) {
+    if (!F->arg_empty()) {
       std::string ArgName;
-      if (F->abegin()->hasName() || !Prototype)
-        ArgName = Mang->getValueName(F->abegin());
-      printType(FunctionInnards, F->afront().getType(), ArgName);
-      for (Function::const_aiterator I = ++F->abegin(), E = F->aend();
+      if (F->arg_begin()->hasName() || !Prototype)
+        ArgName = Mang->getValueName(F->arg_begin());
+      printType(FunctionInnards, F->arg_begin()->getType(), ArgName);
+      for (Function::const_arg_iterator I = ++F->arg_begin(), E = F->arg_end();
            I != E; ++I) {
         FunctionInnards << ", ";
         if (I->hasName() || !Prototype)
@@ -1246,7 +1247,7 @@ void CWriter::visitSwitchInst(SwitchInst &SI) {
     BasicBlock *Succ = cast<BasicBlock>(SI.getOperand(i+1));
     printPHICopiesForSuccessor (SI.getParent(), Succ, 2);
     printBranchToBlock(SI.getParent(), Succ, 2);
-    if (Succ == SI.getParent()->getNext())
+    if (Function::iterator(Succ) == next(Function::iterator(SI.getParent())))
       Out << "    break;\n";
   }
   Out << "  }\n";
@@ -1260,12 +1261,11 @@ bool CWriter::isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) {
   /// FIXME: This should be reenabled, but loop reordering safe!!
   return true;
 
-  if (From->getNext() != To) // Not the direct successor, we need a goto
-    return true; 
+  if (next(Function::iterator(From)) != Function::iterator(To))
+    return true;  // Not the direct successor, we need a goto.
 
   //isa<SwitchInst>(From->getTerminator())
 
-
   if (LI->getLoopFor(From) != LI->getLoopFor(To))
     return true;
   return false;
@@ -1356,30 +1356,38 @@ void CWriter::visitBinaryOperator(Instruction &I) {
     printType(Out, I.getType());
     Out << ")(";
   }
-      
-  writeOperand(I.getOperand(0));
 
-  switch (I.getOpcode()) {
-  case Instruction::Add: Out << " + "; break;
-  case Instruction::Sub: Out << " - "; break;
-  case Instruction::Mul: Out << '*'; break;
-  case Instruction::Div: Out << '/'; break;
-  case Instruction::Rem: Out << '%'; break;
-  case Instruction::And: Out << " & "; break;
-  case Instruction::Or: Out << " | "; break;
-  case Instruction::Xor: Out << " ^ "; break;
-  case Instruction::SetEQ: Out << " == "; break;
-  case Instruction::SetNE: Out << " != "; break;
-  case Instruction::SetLE: Out << " <= "; break;
-  case Instruction::SetGE: Out << " >= "; break;
-  case Instruction::SetLT: Out << " < "; break;
-  case Instruction::SetGT: Out << " > "; break;
-  case Instruction::Shl : Out << " << "; break;
-  case Instruction::Shr : Out << " >> "; break;
-  default: std::cerr << "Invalid operator type!" << I; abort();
-  }
+  // If this is a negation operation, print it out as such.  For FP, we don't
+  // want to print "-0.0 - X".
+  if (BinaryOperator::isNeg(&I)) {
+    Out << "-";
+    writeOperand(BinaryOperator::getNegArgument(cast<BinaryOperator>(&I)));
+
+  } else {
+    writeOperand(I.getOperand(0));
+
+    switch (I.getOpcode()) {
+    case Instruction::Add: Out << " + "; break;
+    case Instruction::Sub: Out << " - "; break;
+    case Instruction::Mul: Out << '*'; break;
+    case Instruction::Div: Out << '/'; break;
+    case Instruction::Rem: Out << '%'; break;
+    case Instruction::And: Out << " & "; break;
+    case Instruction::Or: Out << " | "; break;
+    case Instruction::Xor: Out << " ^ "; break;
+    case Instruction::SetEQ: Out << " == "; break;
+    case Instruction::SetNE: Out << " != "; break;
+    case Instruction::SetLE: Out << " <= "; break;
+    case Instruction::SetGE: Out << " >= "; break;
+    case Instruction::SetLT: Out << " < "; break;
+    case Instruction::SetGT: Out << " > "; break;
+    case Instruction::Shl : Out << " << "; break;
+    case Instruction::Shr : Out << " >> "; break;
+    default: std::cerr << "Invalid operator type!" << I; abort();
+    }
 
-  writeOperand(I.getOperand(1));
+    writeOperand(I.getOperand(1));
+  }
 
   if (needsCast) {
     Out << "))";
@@ -1430,11 +1438,15 @@ void CWriter::lowerIntrinsics(Function &F) {
           case Intrinsic::frameaddress:
           case Intrinsic::setjmp:
           case Intrinsic::longjmp:
+          case Intrinsic::prefetch:
             // We directly implement these intrinsics
             break;
           default:
             // All other intrinsic calls we must lower.
-            Instruction *Before = CI->getPrev();
+            Instruction *Before = 0;
+            if (CI != &BB->front()) 
+              Before = prior(BasicBlock::iterator(CI));
+              
             IL.LowerIntrinsicCall(CI);
             if (Before) {        // Move iterator to instruction after call
               I = Before; ++I;
@@ -1457,13 +1469,13 @@ void CWriter::visitCallInst(CallInst &I) {
         
         Out << "va_start(*(va_list*)&" << Mang->getValueName(&I) << ", ";
         // Output the last argument to the enclosing function...
-        if (I.getParent()->getParent()->aempty()) {
+        if (I.getParent()->getParent()->arg_empty()) {
           std::cerr << "The C backend does not currently support zero "
                     << "argument varargs functions, such as '"
                     << I.getParent()->getParent()->getName() << "'!\n";
           abort();
         }
-        writeOperand(&I.getParent()->getParent()->aback());
+        writeOperand(--I.getParent()->getParent()->arg_end());
         Out << ')';
         return;
       case Intrinsic::vaend:
@@ -1504,6 +1516,15 @@ void CWriter::visitCallInst(CallInst &I) {
         writeOperand(I.getOperand(2));
         Out << ')';
         return;
+      case Intrinsic::prefetch:
+        Out << "LLVM_PREFETCH((const void *)";
+        writeOperand(I.getOperand(1));
+        Out << ", ";
+        writeOperand(I.getOperand(2));
+        Out << ", ";
+        writeOperand(I.getOperand(3));
+        Out << ")";
+        return;
       }
     }
 
@@ -1656,26 +1677,26 @@ void CWriter::printIndexingExpression(Value *Ptr, gep_type_iterator I,
 void CWriter::visitLoadInst(LoadInst &I) {
   Out << '*';
   if (I.isVolatile()) {
-    Out << "((volatile ";
-    printType(Out, I.getOperand(0)->getType());
-    Out << ")";
+    Out << "((";
+    printType(Out, I.getType());
+    Out << " volatile*)";
   }
 
   writeOperand(I.getOperand(0));
 
   if (I.isVolatile())
-    Out << ")";
+    Out << ')';
 }
 
 void CWriter::visitStoreInst(StoreInst &I) {
   Out << '*';
   if (I.isVolatile()) {
-    Out << "((volatile ";
-    printType(Out, I.getPointerOperand()->getType());
-    Out << ")";
+    Out << "((";
+    printType(Out, I.getOperand(0)->getType());
+    Out << " volatile*)";
   }
   writeOperand(I.getPointerOperand());
-  if (I.isVolatile()) Out << ")";
+  if (I.isVolatile()) Out << ')';
   Out << " = ";
   writeOperand(I.getOperand(0));
 }
@@ -1708,7 +1729,7 @@ void CWriter::visitVAArgInst(VAArgInst &I) {
 
 bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) {
   PM.add(createLowerGCPass());
-  PM.add(createLowerAllocationsPass());
+  PM.add(createLowerAllocationsPass(true));
   PM.add(createLowerInvokePass());
   PM.add(new CBackendNameAllUsedStructs());
   PM.add(new CWriter(o, getIntrinsicLowering()));