Remove some redundant checks, add a couple of new ones. This allows us to
[oota-llvm.git] / lib / Target / CBackend / CBackend.cpp
index 16d83c377171f6dfc26b4d73a5a9b077d910fb20..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>
@@ -85,10 +86,15 @@ namespace {
     bool runOnFunction(Function &F) {
       LI = &getAnalysis<LoopInfo>();
 
+      // Get rid of intrinsics we can't handle.
+      lowerIntrinsics(F);
+
       // Output all floating point constants that cannot be printed accurately.
       printFloatingPointConstants(F);
-  
-      lowerIntrinsics(F);
+
+      // Ensure that no local symbols conflict with global symbols.
+      F.renameLocalSymbols();
+
       printFunction(F);
       FPConstantMap.clear();
       return false;
@@ -182,7 +188,6 @@ namespace {
     void visitCastInst (CastInst &I);
     void visitSelectInst(SelectInst &I);
     void visitCallInst (CallInst &I);
-    void visitCallSite (CallSite CS);
     void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
 
     void visitMallocInst(MallocInst &I);
@@ -206,12 +211,11 @@ namespace {
     bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To);
     void printPHICopiesForSuccessor(BasicBlock *CurBlock,
                                     BasicBlock *Successor, unsigned Indent);
-    void printPHICopiesForSuccessors(BasicBlock *CurBlock, 
-                                     unsigned Indent);
     void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
                             unsigned Indent);
     void printIndexingExpression(Value *Ptr, gep_type_iterator I,
                                  gep_type_iterator E);
+    void printCodeForMain();
   };
 }
 
@@ -224,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
@@ -284,7 +287,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
   // Check to see if the type is named.
   if (!IgnoreName || isa<OpaqueType>(Ty)) {
     std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty);
-    if (I != TypeNames.end()) return Out << I->second << " " << NameSoFar;
+    if (I != TypeNames.end()) return Out << I->second << ' ' << NameSoFar;
   }
 
   switch (Ty->getTypeID()) {
@@ -304,7 +307,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
     } else if (!MTy->getNumParams()) {
       FunctionInnards << "void";
     }
-    FunctionInnards << ")";
+    FunctionInnards << ')';
     std::string tstr = FunctionInnards.str();
     printType(Out, MTy->getReturnType(), tstr);
     return Out;
@@ -319,7 +322,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
       printType(Out, *I, "field" + utostr(Idx++));
       Out << ";\n";
     }
-    return Out << "}";
+    return Out << '}';
   }  
 
   case Type::PointerTyID: {
@@ -335,6 +338,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
   case Type::ArrayTyID: {
     const ArrayType *ATy = cast<ArrayType>(Ty);
     unsigned NumElements = ATy->getNumElements();
+    if (NumElements == 0) NumElements = 1;
     return printType(Out, ATy->getElementType(),
                      NameSoFar + "[" + utostr(NumElements) + "]");
   }
@@ -344,7 +348,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
     std::string TyName = "struct opaque_" + itostr(Count++);
     assert(TypeNames.find(Ty) == TypeNames.end());
     TypeNames[Ty] = TyName;
-    return Out << TyName << " " << NameSoFar;
+    return Out << TyName << ' ' << NameSoFar;
   }
   default:
     assert(0 && "Unhandled case in getTypeProps!");
@@ -368,7 +372,7 @@ void CWriter::printConstantArray(ConstantArray *CPA) {
     isString = false;
   
   if (isString) {
-    Out << "\"";
+    Out << '\"';
     // Keep track of whether the last number was a hexadecimal escape
     bool LastWasHex = false;
 
@@ -407,11 +411,11 @@ void CWriter::printConstantArray(ConstantArray *CPA) {
         }
       }
     }
-    Out << "\"";
+    Out << '\"';
   } else {
-    Out << "{";
+    Out << '{';
     if (CPA->getNumOperands()) {
-      Out << " ";
+      Out << ' ';
       printConstant(cast<Constant>(CPA->getOperand(0)));
       for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) {
         Out << ", ";
@@ -464,9 +468,9 @@ void CWriter::printConstant(Constant *CPV) {
     case Instruction::Cast:
       Out << "((";
       printType(Out, CPV->getType());
-      Out << ")";
+      Out << ')';
       printConstant(CE->getOperand(0));
-      Out << ")";
+      Out << ')';
       return;
 
     case Instruction::GetElementPtr:
@@ -476,19 +480,22 @@ void CWriter::printConstant(Constant *CPV) {
       Out << "))";
       return;
     case Instruction::Select:
-      Out << "(";
+      Out << '(';
       printConstant(CE->getOperand(0));
-      Out << "?";
+      Out << '?';
       printConstant(CE->getOperand(1));
-      Out << ":";
+      Out << ':';
       printConstant(CE->getOperand(2));
-      Out << ")";
+      Out << ')';
       return;
     case Instruction::Add:
     case Instruction::Sub:
     case Instruction::Mul:
     case Instruction::Div:
     case Instruction::Rem:
+    case Instruction::And:
+    case Instruction::Or:
+    case Instruction::Xor:
     case Instruction::SetEQ:
     case Instruction::SetNE:
     case Instruction::SetLT:
@@ -497,7 +504,7 @@ void CWriter::printConstant(Constant *CPV) {
     case Instruction::SetGE:
     case Instruction::Shl:
     case Instruction::Shr:
-      Out << "(";
+      Out << '(';
       printConstant(CE->getOperand(0));
       switch (CE->getOpcode()) {
       case Instruction::Add: Out << " + "; break;
@@ -505,6 +512,9 @@ void CWriter::printConstant(Constant *CPV) {
       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::SetLT: Out << " < "; break;
@@ -516,7 +526,7 @@ void CWriter::printConstant(Constant *CPV) {
       default: assert(0 && "Illegal opcode here!");
       }
       printConstant(CE->getOperand(1));
-      Out << ")";
+      Out << ')';
       return;
 
     default:
@@ -533,25 +543,28 @@ void CWriter::printConstant(Constant *CPV) {
 
   switch (CPV->getType()->getTypeID()) {
   case Type::BoolTyID:
-    Out << (CPV == ConstantBool::False ? "0" : "1"); break;
+    Out << (CPV == ConstantBool::False ? '0' : '1'); break;
   case Type::SByteTyID:
   case Type::ShortTyID:
     Out << cast<ConstantSInt>(CPV)->getValue(); break;
   case Type::IntTyID:
     if ((int)cast<ConstantSInt>(CPV)->getValue() == (int)0x80000000)
-      Out << "((int)0x80000000)";   // Handle MININT specially to avoid warning
+      Out << "((int)0x80000000U)";   // Handle MININT specially to avoid warning
     else
       Out << cast<ConstantSInt>(CPV)->getValue();
     break;
 
   case Type::LongTyID:
-    Out << cast<ConstantSInt>(CPV)->getValue() << "ll"; break;
+    if (cast<ConstantSInt>(CPV)->isMinValue())
+      Out << "(/*INT64_MIN*/(-9223372036854775807LL)-1)";
+    else
+      Out << cast<ConstantSInt>(CPV)->getValue() << "ll"; break;
 
   case Type::UByteTyID:
   case Type::UShortTyID:
     Out << cast<ConstantUInt>(CPV)->getValue(); break;
   case Type::UIntTyID:
-    Out << cast<ConstantUInt>(CPV)->getValue() << "u"; break;
+    Out << cast<ConstantUInt>(CPV)->getValue() << 'u'; break;
   case Type::ULongTyID:
     Out << cast<ConstantUInt>(CPV)->getValue() << "ull"; break;
 
@@ -563,7 +576,7 @@ void CWriter::printConstant(Constant *CPV) {
       // Because of FP precision problems we must load from a stack allocated
       // value that holds the value in hex.
       Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double")
-          << "*)&FPConstant" << I->second << ")";
+          << "*)&FPConstant" << I->second << ')';
     } else {
       if (IsNAN(FPC->getValue())) {
         // The value is NaN
@@ -594,7 +607,7 @@ void CWriter::printConstant(Constant *CPV) {
               << Buffer << "\") /*nan*/ ";
       } else if (IsInf(FPC->getValue())) {
         // The value is Inf
-        if (FPC->getValue() < 0) Out << "-";
+        if (FPC->getValue() < 0) Out << '-';
         Out << "LLVM_INF" << (FPC->getType() == Type::FloatTy ? "F" : "")
             << " /*inf*/ ";
       } else {
@@ -616,9 +629,9 @@ void CWriter::printConstant(Constant *CPV) {
   case Type::ArrayTyID:
     if (isa<ConstantAggregateZero>(CPV) || isa<UndefValue>(CPV)) {
       const ArrayType *AT = cast<ArrayType>(CPV->getType());
-      Out << "{";
+      Out << '{';
       if (AT->getNumElements()) {
-        Out << " ";
+        Out << ' ';
         Constant *CZ = Constant::getNullValue(AT->getElementType());
         printConstant(CZ);
         for (unsigned i = 1, e = AT->getNumElements(); i != e; ++i) {
@@ -635,9 +648,9 @@ void CWriter::printConstant(Constant *CPV) {
   case Type::StructTyID:
     if (isa<ConstantAggregateZero>(CPV) || isa<UndefValue>(CPV)) {
       const StructType *ST = cast<StructType>(CPV->getType());
-      Out << "{";
+      Out << '{';
       if (ST->getNumElements()) {
-        Out << " ";
+        Out << ' ';
         printConstant(Constant::getNullValue(ST->getElementType(0)));
         for (unsigned i = 1, e = ST->getNumElements(); i != e; ++i) {
           Out << ", ";
@@ -646,9 +659,9 @@ void CWriter::printConstant(Constant *CPV) {
       }
       Out << " }";
     } else {
-      Out << "{";
+      Out << '{';
       if (CPV->getNumOperands()) {
-        Out << " ";
+        Out << ' ';
         printConstant(cast<Constant>(CPV->getOperand(0)));
         for (unsigned i = 1, e = CPV->getNumOperands(); i != e; ++i) {
           Out << ", ";
@@ -680,9 +693,9 @@ void CWriter::writeOperandInternal(Value *Operand) {
   if (Instruction *I = dyn_cast<Instruction>(Operand))
     if (isInlinableInst(*I) && !isDirectAlloca(I)) {
       // Should we inline this instruction to build a tree?
-      Out << "(";
+      Out << '(';
       visit(*I);
-      Out << ")";    
+      Out << ')';
       return;
     }
   
@@ -701,7 +714,7 @@ void CWriter::writeOperand(Value *Operand) {
   writeOperandInternal(Operand);
 
   if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand))
-    Out << ")";
+    Out << ')';
 }
 
 // generateCompilerSpecificCode - This is where we add conditional compilation
@@ -710,12 +723,22 @@ void CWriter::writeOperand(Value *Operand) {
 static void generateCompilerSpecificCode(std::ostream& Out) {
   // Alloca is hard to get, and we don't want to include stdlib.h here...
   Out << "/* get a declaration for alloca */\n"
-      << "#if defined(sun) || defined(__CYGWIN__) || defined(__APPLE__)\n"
+      << "#if defined(__CYGWIN__)\n"
+      << "extern void *_alloca(unsigned long);\n"
+      << "#define alloca(x) _alloca(x)\n"
+      << "#elif defined(__APPLE__)\n"
       << "extern void *__builtin_alloca(unsigned long);\n"
       << "#define alloca(x) __builtin_alloca(x)\n"
+      << "#elif defined(__sun__)\n"
+      << "#if defined(__sparcv9)\n"
+      << "extern void *__builtin_alloca(unsigned long);\n"
+      << "#else\n"
+      << "extern void *__builtin_alloca(unsigned int);\n"
+      << "#endif\n"
+      << "#define alloca(x) __builtin_alloca(x)\n"
       << "#elif defined(__FreeBSD__)\n"
       << "#define alloca(x) __builtin_alloca(x)\n"
-      << "#else\n"
+      << "#elif !defined(_MSC_VER)\n"
       << "#include <alloca.h>\n"
       << "#endif\n\n";
 
@@ -784,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"
@@ -791,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";
 }
 
@@ -827,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));
@@ -854,11 +879,14 @@ 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()) {
-        Out << "extern ";
+        if (I->hasInternalLinkage())
+          Out << "static ";
+        else
+          Out << "extern ";
         printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
 
         if (I->hasLinkOnceLinkage())
@@ -870,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 ";
@@ -954,7 +982,7 @@ void CWriter::printFloatingPointConstants(Function &F) {
           assert(0 && "Unknown float type!");
       }
   
-  Out << "\n";
+  Out << '\n';
 }
 
 
@@ -962,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";
@@ -979,7 +1006,7 @@ void CWriter::printModuleTypes(const SymbolTable &ST) {
       TypeNames.insert(std::make_pair(STy, Name));
     }
 
-  Out << "\n";
+  Out << '\n';
 
   // Now we can print out typedefs...
   Out << "/* Typedefs */\n";
@@ -991,7 +1018,7 @@ void CWriter::printModuleTypes(const SymbolTable &ST) {
     Out << ";\n";
   }
   
-  Out << "\n";
+  Out << '\n';
 
   // Keep track of which structures have been printed so far...
   std::set<const StructType *> StructPrinted;
@@ -1046,15 +1073,15 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   std::stringstream FunctionInnards; 
     
   // Print out the name...
-  FunctionInnards << Mang->getValueName(F) << "(";
+  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)
@@ -1082,7 +1109,7 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   } else if (!FT->isVarArg() && FT->getNumParams() == 0) {
     FunctionInnards << "void"; // ret() -> ret(void) in C.
   }
-  FunctionInnards << ")";
+  FunctionInnards << ')';
   // Print out the return type and the entire signature for that matter
   printType(Out, F->getReturnType(), FunctionInnards.str());
 }
@@ -1096,7 +1123,7 @@ void CWriter::printFunction(Function &F) {
     if (const AllocaInst *AI = isDirectAlloca(&*I)) {
       Out << "  ";
       printType(Out, AI->getAllocatedType(), Mang->getValueName(AI));
-      Out << ";    /* Address exposed local */\n";
+      Out << ";    /* Address-exposed local */\n";
     } else if (I->getType() != Type::VoidTy && !isInlinableInst(*I)) {
       Out << "  ";
       printType(Out, I->getType(), Mang->getValueName(&*I));
@@ -1110,7 +1137,10 @@ void CWriter::printFunction(Function &F) {
       }
     }
 
-  Out << "\n";
+  Out << '\n';
+
+  if (F.hasExternalLinkage() && F.getName() == "main")
+    printCodeForMain();
 
   // print the basic blocks
   for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
@@ -1125,6 +1155,15 @@ void CWriter::printFunction(Function &F) {
   Out << "}\n\n";
 }
 
+void CWriter::printCodeForMain() {
+  // On X86, set the FP control word to 64-bits of precision instead of 80 bits.
+  Out << "#if defined(__GNUC__) && !defined(__llvm__)\n"
+      << "#if defined(i386) || defined(__i386__) || defined(__i386)\n"
+      << "{short FPCW;__asm__ (\"fnstcw %0\" : \"=m\" (*&FPCW));\n"
+      << "FPCW=(FPCW&~0x300)|0x200;__asm__(\"fldcw %0\" :: \"m\" (*&FPCW));}\n"
+      << "#endif\n#endif\n";
+}
+
 void CWriter::printLoop(Loop *L) {
   Out << "  do {     /* Syntactic loop '" << L->getHeader()->getName()
       << "' to make GCC happy */\n";
@@ -1187,7 +1226,7 @@ void CWriter::visitReturnInst(ReturnInst &I) {
 
   Out << "  return";
   if (I.getNumOperands()) {
-    Out << " ";
+    Out << ' ';
     writeOperand(I.getOperand(0));
   }
   Out << ";\n";
@@ -1208,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";
@@ -1222,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;
@@ -1249,25 +1287,6 @@ void CWriter::printPHICopiesForSuccessor (BasicBlock *CurBlock,
   }
 }
 
-
-void CWriter::printPHICopiesForSuccessors(BasicBlock *CurBlock, 
-                                          unsigned Indent) {
-  for (succ_iterator SI = succ_begin(CurBlock), E = succ_end(CurBlock);
-       SI != E; ++SI)
-    for (BasicBlock::iterator I = SI->begin(); isa<PHINode>(I); ++I) {
-      PHINode *PN = cast<PHINode>(I);
-      // Now we have to do the printing.
-      Value *IV = PN->getIncomingValueForBlock(CurBlock);
-      if (!isa<UndefValue>(IV)) {
-        Out << std::string(Indent, ' ');
-        Out << "  " << Mang->getValueName(I) << "__PHI_TEMPORARY = ";
-        writeOperand(IV);
-        Out << ";   /* for PHI node */\n";
-      }
-    }
-}
-
-
 void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ,
                                  unsigned Indent) {
   if (isGotoCodeNecessary(CurBB, Succ)) {
@@ -1337,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));
 
-  writeOperand(I.getOperand(1));
+    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));
+  }
 
   if (needsCast) {
     Out << "))";
@@ -1369,14 +1396,14 @@ void CWriter::visitBinaryOperator(Instruction &I) {
 
 void CWriter::visitCastInst(CastInst &I) {
   if (I.getType() == Type::BoolTy) {
-    Out << "(";
+    Out << '(';
     writeOperand(I.getOperand(0));
     Out << " != 0)";
     return;
   }
-  Out << "(";
+  Out << '(';
   printType(Out, I.getType());
-  Out << ")";
+  Out << ')';
   if (isa<PointerType>(I.getType())&&I.getOperand(0)->getType()->isIntegral() ||
       isa<PointerType>(I.getOperand(0)->getType())&&I.getType()->isIntegral()) {
     // Avoid "cast to pointer from integer of different size" warnings
@@ -1411,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;
@@ -1438,20 +1469,20 @@ 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());
-        Out << ")";
+        writeOperand(--I.getParent()->getParent()->arg_end());
+        Out << ')';
         return;
       case Intrinsic::vaend:
         if (!isa<ConstantPointerNull>(I.getOperand(1))) {
           Out << "va_end(*(va_list*)&";
           writeOperand(I.getOperand(1));
-          Out << ")";
+          Out << ')';
         } else {
           Out << "va_end(*(va_list*)0)";
         }
@@ -1461,53 +1492,110 @@ void CWriter::visitCallInst(CallInst &I) {
         Out << "va_copy(*(va_list*)&" << Mang->getValueName(&I) << ", ";
         Out << "*(va_list*)&";
         writeOperand(I.getOperand(1));
-        Out << ")";
+        Out << ')';
         return;
       case Intrinsic::returnaddress:
         Out << "__builtin_return_address(";
         writeOperand(I.getOperand(1));
-        Out << ")";
+        Out << ')';
         return;
       case Intrinsic::frameaddress:
         Out << "__builtin_frame_address(";
         writeOperand(I.getOperand(1));
-        Out << ")";
+        Out << ')';
         return;
       case Intrinsic::setjmp:
         Out << "setjmp(*(jmp_buf*)";
         writeOperand(I.getOperand(1));
-        Out << ")";
+        Out << ')';
         return;
       case Intrinsic::longjmp:
         Out << "longjmp(*(jmp_buf*)";
         writeOperand(I.getOperand(1));
         Out << ", ";
         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;
       }
     }
-  visitCallSite(&I);
-}
 
-void CWriter::visitCallSite(CallSite CS) {
-  const PointerType  *PTy   = cast<PointerType>(CS.getCalledValue()->getType());
+  Value *Callee = I.getCalledValue();
+  
+  // GCC is really a PITA.  It does not permit codegening casts of functions to
+  // function pointers if they are in a call (it generates a trap instruction
+  // instead!).  We work around this by inserting a cast to void* in between the
+  // function and the function pointer cast.  Unfortunately, we can't just form
+  // the constant expression here, because the folder will immediately nuke it.
+  //
+  // Note finally, that this is completely unsafe.  ANSI C does not guarantee
+  // that void* and function pointers have the same size. :( To deal with this
+  // in the common case, we handle casts where the number of arguments passed
+  // match exactly.
+  //
+  bool WroteCallee = false;
+  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Callee))
+    if (CE->getOpcode() == Instruction::Cast)
+      if (Function *RF = dyn_cast<Function>(CE->getOperand(0))) {
+        const FunctionType *RFTy = RF->getFunctionType();
+        if (RFTy->getNumParams() == I.getNumOperands()-1) {
+          // If the call site expects a value, and the actual callee doesn't
+          // provide one, return 0.
+          if (I.getType() != Type::VoidTy &&
+              RFTy->getReturnType() == Type::VoidTy)
+            Out << "0 /*actual callee doesn't return value*/; ";
+          Callee = RF;
+        } else {
+          // Ok, just cast the pointer type.
+          Out << "((";
+          printType(Out, CE->getType());
+          Out << ")(void*)";
+          printConstant(RF);
+          Out << ')';
+          WroteCallee = true;
+        }
+      }
+
+  const PointerType  *PTy   = cast<PointerType>(Callee->getType());
   const FunctionType *FTy   = cast<FunctionType>(PTy->getElementType());
   const Type         *RetTy = FTy->getReturnType();
   
-  writeOperand(CS.getCalledValue());
-  Out << "(";
+  if (!WroteCallee) writeOperand(Callee);
+  Out << '(';
+
+  unsigned NumDeclaredParams = FTy->getNumParams();
+
+  if (I.getNumOperands() != 1) {
+    CallSite::arg_iterator AI = I.op_begin()+1, AE = I.op_end();
+    if (NumDeclaredParams && (*AI)->getType() != FTy->getParamType(0)) {
+      Out << '(';
+      printType(Out, FTy->getParamType(0));
+      Out << ')';
+    }
 
-  if (CS.arg_begin() != CS.arg_end()) {
-    CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
     writeOperand(*AI);
 
-    for (++AI; AI != AE; ++AI) {
+    unsigned ArgNo;
+    for (ArgNo = 1, ++AI; AI != AE; ++AI, ++ArgNo) {
       Out << ", ";
+      if (ArgNo < NumDeclaredParams &&
+          (*AI)->getType() != FTy->getParamType(ArgNo)) {
+        Out << '(';
+        printType(Out, FTy->getParamType(ArgNo));
+        Out << ')';
+      }
       writeOperand(*AI);
     }
   }
-  Out << ")";
+  Out << ')';
 }  
 
 void CWriter::visitMallocInst(MallocInst &I) {
@@ -1515,16 +1603,16 @@ void CWriter::visitMallocInst(MallocInst &I) {
 }
 
 void CWriter::visitAllocaInst(AllocaInst &I) {
-  Out << "(";
+  Out << '(';
   printType(Out, I.getType());
   Out << ") alloca(sizeof(";
   printType(Out, I.getType()->getElementType());
-  Out << ")";
+  Out << ')';
   if (I.isArrayAllocation()) {
     Out << " * " ;
     writeOperand(I.getOperand(0));
   }
-  Out << ")";
+  Out << ')';
 }
 
 void CWriter::visitFreeInst(FreeInst &I) {
@@ -1543,7 +1631,7 @@ void CWriter::printIndexingExpression(Value *Ptr, gep_type_iterator I,
 
   if (I == E) {
     if (!HasImplicitAddress)
-      Out << "*";  // Implicit zero first argument: '*x' is equivalent to 'x[0]'
+      Out << '*';  // Implicit zero first argument: '*x' is equivalent to 'x[0]'
 
     writeOperandInternal(Ptr);
     return;
@@ -1556,7 +1644,7 @@ void CWriter::printIndexingExpression(Value *Ptr, gep_type_iterator I,
   writeOperandInternal(Ptr);
 
   if (HasImplicitAddress && (!CI || !CI->isNullValue())) {
-    Out << ")";
+    Out << ')';
     HasImplicitAddress = false;  // HIA is only true if we haven't addressed yet
   }
 
@@ -1580,26 +1668,41 @@ void CWriter::printIndexingExpression(Value *Ptr, gep_type_iterator I,
     if (isa<StructType>(*I)) {
       Out << ".field" << cast<ConstantUInt>(I.getOperand())->getValue();
     } else {
-      Out << "[";
+      Out << '[';
       writeOperand(I.getOperand());
-      Out << "]";
+      Out << ']';
     }
 }
 
 void CWriter::visitLoadInst(LoadInst &I) {
-  Out << "*";
+  Out << '*';
+  if (I.isVolatile()) {
+    Out << "((";
+    printType(Out, I.getType());
+    Out << " volatile*)";
+  }
+
   writeOperand(I.getOperand(0));
+
+  if (I.isVolatile())
+    Out << ')';
 }
 
 void CWriter::visitStoreInst(StoreInst &I) {
-  Out << "*";
+  Out << '*';
+  if (I.isVolatile()) {
+    Out << "((";
+    printType(Out, I.getOperand(0)->getType());
+    Out << " volatile*)";
+  }
   writeOperand(I.getPointerOperand());
+  if (I.isVolatile()) Out << ')';
   Out << " = ";
   writeOperand(I.getOperand(0));
 }
 
 void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
-  Out << "&";
+  Out << '&';
   printIndexingExpression(I.getPointerOperand(), gep_type_begin(I),
                           gep_type_end(I));
 }
@@ -1608,7 +1711,7 @@ void CWriter::visitVANextInst(VANextInst &I) {
   Out << Mang->getValueName(I.getOperand(0));
   Out << ";  va_arg(*(va_list*)&" << Mang->getValueName(&I) << ", ";
   printType(Out, I.getArgType());
-  Out << ")";  
+  Out << ')';  
 }
 
 void CWriter::visitVAArgInst(VAArgInst &I) {
@@ -1626,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()));