[llvm-commits] CVS: llvm/lib/CWriter/Writer.cpp

John Criswell criswell at choi.cs.uiuc.edu
Thu Jun 26 16:38:23 PDT 2003


Changes in directory llvm/lib/CWriter:

Writer.cpp updated: 1.92 -> 1.92.2.1

---
Log message:

Merged with mainline on Thursday, June 26, 2003.


---
Diffs of the changes:

Index: llvm/lib/CWriter/Writer.cpp
diff -u llvm/lib/CWriter/Writer.cpp:1.92 llvm/lib/CWriter/Writer.cpp:1.92.2.1
--- llvm/lib/CWriter/Writer.cpp:1.92	Fri Jun  6 02:10:24 2003
+++ llvm/lib/CWriter/Writer.cpp	Thu Jun 26 16:35:15 2003
@@ -97,6 +97,20 @@
       return I.getParent() == cast<Instruction>(I.use_back())->getParent();
     }
 
+    // isDirectAlloca - Define fixed sized allocas in the entry block as direct
+    // variables which are accessed with the & operator.  This causes GCC to
+    // generate significantly better code than to emit alloca calls directly.
+    //
+    static const AllocaInst *isDirectAlloca(const Value *V) {
+      const AllocaInst *AI = dyn_cast<AllocaInst>(V);
+      if (!AI) return false;
+      if (AI->isArrayAllocation())
+        return 0;   // FIXME: we can also inline fixed size array allocas!
+      if (AI->getParent() != &AI->getParent()->getParent()->getEntryNode())
+        return 0;
+      return AI;
+    }
+
     // Instruction visitation functions
     friend class InstVisitor<CWriter>;
 
@@ -150,14 +164,25 @@
 }
 
 std::string CWriter::getValueName(const Value *V) {
-  if (V->hasName()) {              // Print out the label if it exists...
-    if (isa<GlobalValue>(V) &&     // Do not mangle globals...
-        (cast<GlobalValue>(V)->hasExternalLinkage() &&// Unless it's internal or
-         !MangledGlobals.count(V))) // Unless the name would collide if we don't
-      return makeNameProper(V->getName());
-
+  if (V->hasName()) { // Print out the label if it exists...
+    
+    // Name mangling occurs as follows:
+    // - If V is not a global, mangling always occurs.
+    // - Otherwise, mangling occurs when any of the following are true:
+    //   1) V has internal linkage
+    //   2) V's name would collide if it is not mangled.
+    //
+    
+    if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
+      if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
+        // No internal linkage, name will not collide -> no mangling.
+        return makeNameProper(gv->getName());
+      }
+    }
+    
+    // Non-global, or global with internal linkage / colliding name -> mangle.
     return "l" + utostr(V->getType()->getUniqueID()) + "_" +
-           makeNameProper(V->getName());      
+      makeNameProper(V->getName());      
   }
 
   int Slot = Table->getValSlot(V);
@@ -206,23 +231,23 @@
   switch (Ty->getPrimitiveID()) {
   case Type::FunctionTyID: {
     const FunctionType *MTy = cast<FunctionType>(Ty);
-    std::stringstream FunctionInards; 
-    FunctionInards << " (" << NameSoFar << ") (";
+    std::stringstream FunctionInnards; 
+    FunctionInnards << " (" << NameSoFar << ") (";
     for (FunctionType::ParamTypes::const_iterator
            I = MTy->getParamTypes().begin(),
            E = MTy->getParamTypes().end(); I != E; ++I) {
       if (I != MTy->getParamTypes().begin())
-        FunctionInards << ", ";
-      printType(FunctionInards, *I, "");
+        FunctionInnards << ", ";
+      printType(FunctionInnards, *I, "");
     }
     if (MTy->isVarArg()) {
       if (!MTy->getParamTypes().empty()) 
-    	FunctionInards << ", ...";
+    	FunctionInnards << ", ...";
     } else if (MTy->getParamTypes().empty()) {
-      FunctionInards << "void";
+      FunctionInnards << "void";
     }
-    FunctionInards << ")";
-    std::string tstr = FunctionInards.str();
+    FunctionInnards << ")";
+    std::string tstr = FunctionInnards.str();
     printType(Out, MTy->getReturnType(), tstr);
     return Out;
   }
@@ -285,24 +310,35 @@
   bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
 
   // Make sure the last character is a null char, as automatically added by C
-  if (CPA->getNumOperands() == 0 ||
-      !cast<Constant>(*(CPA->op_end()-1))->isNullValue())
+  if (isString && (CPA->getNumOperands() == 0 ||
+                   !cast<Constant>(*(CPA->op_end()-1))->isNullValue()))
     isString = false;
   
   if (isString) {
     Out << "\"";
+    // Keep track of whether the last number was a hexadecimal escape
+    bool LastWasHex = false;
+
     // Do not include the last character, which we know is null
     for (unsigned i = 0, e = CPA->getNumOperands()-1; i != e; ++i) {
       unsigned char C = (ETy == Type::SByteTy) ?
         (unsigned char)cast<ConstantSInt>(CPA->getOperand(i))->getValue() :
         (unsigned char)cast<ConstantUInt>(CPA->getOperand(i))->getValue();
       
-      if (isprint(C)) {
+      // Print it out literally if it is a printable character.  The only thing
+      // to be careful about is when the last letter output was a hex escape
+      // code, in which case we have to be careful not to print out hex digits
+      // explicitly (the C compiler thinks it is a continuation of the previous
+      // character, sheesh...)
+      //
+      if (isprint(C) && (!LastWasHex || !isxdigit(C))) {
+        LastWasHex = false;
         if (C == '"' || C == '\\')
           Out << "\\" << C;
         else
           Out << C;
       } else {
+        LastWasHex = false;
         switch (C) {
         case '\n': Out << "\\n"; break;
         case '\t': Out << "\\t"; break;
@@ -313,8 +349,9 @@
         case '\'': Out << "\\\'"; break;           
         default:
           Out << "\\x";
-          Out << ( C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A');
-          Out << ((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A');
+          Out << (char)(( C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'));
+          Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
+          LastWasHex = true;
           break;
         }
       }
@@ -334,6 +371,27 @@
   }
 }
 
+/// FPCSafeToPrint - Returns true if we may assume that CFP may be
+/// written out textually as a double (rather than as a reference to a
+/// stack-allocated variable). We decide this by converting CFP to a
+/// string and back into a double, and then checking whether the
+/// conversion results in a bit-equal double to the original value of
+/// CFP. This depends on us and the target C compiler agreeing on the
+/// conversion process (which is pretty likely since we only deal in
+/// IEEE FP.) This is adapted from similar code in
+/// lib/VMCore/AsmWriter.cpp:WriteConstantInt().
+static bool FPCSafeToPrint (const ConstantFP *CFP) {
+  std::string StrVal = ftostr(CFP->getValue());
+  // Check to make sure that the stringized number is not some string like
+  // "Inf" or NaN, that atof will accept, but the lexer will not.  Check that
+  // the string matches the "[-+]?[0-9]" regex.
+  if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+      ((StrVal[0] == '-' || StrVal[0] == '+') &&
+       (StrVal[1] >= '0' && StrVal[1] <= '9')))
+    // Reparse stringized version!
+    return (atof(StrVal.c_str()) == CFP->getValue());
+  return false;
+}
 
 // printConstant - The LLVM Constant to C Constant converter.
 void CWriter::printConstant(Constant *CPV) {
@@ -409,7 +467,11 @@
       Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double")
           << "*)&FloatConstant" << I->second << ")";
     } else {
-      Out << FPC->getValue();
+      if (FPCSafeToPrint (FPC)) {
+	Out << ftostr (FPC->getValue ());
+      } else {
+	Out << FPC->getValue(); // Who knows? Give it our best shot...
+      }
     }
     break;
   }
@@ -451,7 +513,7 @@
 
 void CWriter::writeOperandInternal(Value *Operand) {
   if (Instruction *I = dyn_cast<Instruction>(Operand))
-    if (isInlinableInst(*I)) {
+    if (isInlinableInst(*I) && !isDirectAlloca(I)) {
       // Should we inline this instruction to build a tree?
       Out << "(";
       visit(*I);
@@ -471,12 +533,12 @@
 }
 
 void CWriter::writeOperand(Value *Operand) {
-  if (isa<GlobalVariable>(Operand))
+  if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand))
     Out << "(&";  // Global variables are references as their addresses by llvm
 
   writeOperandInternal(Operand);
 
-  if (isa<GlobalVariable>(Operand))
+  if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand))
     Out << ")";
 }
 
@@ -516,7 +578,9 @@
       << "extern void *__builtin_alloca(unsigned long);\n"
       << "#define alloca(x) __builtin_alloca(x)\n"
       << "#else\n"
+      << "#ifndef __FreeBSD__\n"
       << "#include <alloca.h>\n"
+      << "#endif\n"
       << "#endif\n\n";
 }
 
@@ -597,9 +661,9 @@
     Out << "extern void * malloc(size_t);\n\n";
   }
 
-  // Output the global variable declerations
+  // Output the global variable declarations
   if (!M->gempty()) {
-    Out << "\n\n/* Global Variable Declerations */\n";
+    Out << "\n\n/* Global Variable Declarations */\n";
     for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
       if (!I->isExternal()) {
         Out << "extern ";
@@ -715,33 +779,36 @@
 
 
 void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
-  // If the program provides it's own malloc prototype we don't need
+  // If the program provides its own malloc prototype we don't need
   // to include the general one.  
   if (getValueName(F) == "malloc")
     needsMalloc = false;
-  if (F->hasInternalLinkage()) Out << "static ";  
+
+  if (F->hasInternalLinkage()) Out << "static ";
+  if (F->hasLinkOnceLinkage()) Out << "inline ";
+  
   // Loop over the arguments, printing them...
   const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
   
-  std::stringstream FunctionInards; 
+  std::stringstream FunctionInnards; 
     
   // Print out the name...
-  FunctionInards << getValueName(F) << "(";
+  FunctionInnards << getValueName(F) << "(";
     
   if (!F->isExternal()) {
     if (!F->aempty()) {
       std::string ArgName;
       if (F->abegin()->hasName() || !Prototype)
         ArgName = getValueName(F->abegin());
-      printType(FunctionInards, F->afront().getType(), ArgName);
+      printType(FunctionInnards, F->afront().getType(), ArgName);
       for (Function::const_aiterator I = ++F->abegin(), E = F->aend();
            I != E; ++I) {
-        FunctionInards << ", ";
+        FunctionInnards << ", ";
         if (I->hasName() || !Prototype)
           ArgName = getValueName(I);
         else 
           ArgName = "";
-        printType(FunctionInards, I->getType(), ArgName);
+        printType(FunctionInnards, I->getType(), ArgName);
       }
     }
   } else {
@@ -749,8 +816,8 @@
     for (FunctionType::ParamTypes::const_iterator I = 
 	   FT->getParamTypes().begin(),
 	   E = FT->getParamTypes().end(); I != E; ++I) {
-      if (I != FT->getParamTypes().begin()) FunctionInards << ", ";
-      printType(FunctionInards, *I);
+      if (I != FT->getParamTypes().begin()) FunctionInnards << ", ";
+      printType(FunctionInnards, *I);
     }
   }
 
@@ -758,16 +825,15 @@
   // unless there are no known types, in which case, we just emit ().
   //
   if (FT->isVarArg() && !FT->getParamTypes().empty()) {
-    if (FT->getParamTypes().size()) FunctionInards << ", ";
-    FunctionInards << "...";  // Output varargs portion of signature!
+    if (FT->getParamTypes().size()) FunctionInnards << ", ";
+    FunctionInnards << "...";  // Output varargs portion of signature!
   }
-  FunctionInards << ")";
+  FunctionInnards << ")";
   // Print out the return type and the entire signature for that matter
-  printType(Out, F->getReturnType(), FunctionInards.str());
+  printType(Out, F->getReturnType(), FunctionInnards.str());
   
 }
 
-
 void CWriter::printFunction(Function *F) {
   if (F->isExternal()) return;
 
@@ -778,11 +844,15 @@
 
   // print local variable information for the function
   for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
-    if ((*I)->getType() != Type::VoidTy && !isInlinableInst(**I)) {
+    if (const AllocaInst *AI = isDirectAlloca(*I)) {
+      Out << "  ";
+      printType(Out, AI->getAllocatedType(), getValueName(AI));
+      Out << ";    /* Address exposed local */\n";
+    } else if ((*I)->getType() != Type::VoidTy && !isInlinableInst(**I)) {
       Out << "  ";
       printType(Out, (*I)->getType(), getValueName(*I));
       Out << ";\n";
-
+      
       if (isa<PHINode>(*I)) {  // Print out PHI node temporaries as well...
         Out << "  ";
         printType(Out, (*I)->getType(), getValueName(*I)+"__PHI_TEMPORARY");
@@ -794,12 +864,14 @@
 
   // Scan the function for floating point constants.  If any FP constant is used
   // in the function, we want to redirect it here so that we do not depend on
-  // the precision of the printed form.
+  // the precision of the printed form, unless the printed form preserves
+  // precision.
   //
   unsigned FPCounter = 0;
   for (constant_iterator I = constant_begin(F), E = constant_end(F); I != E;++I)
     if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
-      if (FPConstantMap.find(FPC) == FPConstantMap.end()) {
+      if ((!FPCSafeToPrint(FPC)) // Do not put in FPConstantMap if safe.
+	  && (FPConstantMap.find(FPC) == FPConstantMap.end())) {
         double Val = FPC->getValue();
         
         FPConstantMap[FPC] = FPCounter;  // Number the FP constants
@@ -842,7 +914,7 @@
 
     // Output all of the instructions in the basic block...
     for (BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; ++II){
-      if (!isInlinableInst(*II)) {
+      if (!isInlinableInst(*II) && !isDirectAlloca(II)) {
         if (II->getType() != Type::VoidTy)
           outputLValue(II);
         else
@@ -971,6 +1043,17 @@
 void CWriter::visitBinaryOperator(Instruction &I) {
   // binary instructions, shift instructions, setCond instructions.
   assert(!isa<PointerType>(I.getType()));
+
+  // We must cast the results of binary operations which might be promoted.
+  bool needsCast = false;
+  if ((I.getType() == Type::UByteTy) || (I.getType() == Type::SByteTy)
+      || (I.getType() == Type::UShortTy) || (I.getType() == Type::ShortTy)
+      || (I.getType() == Type::FloatTy)) {
+    needsCast = true;
+    Out << "((";
+    printType(Out, I.getType(), "", false, false);
+    Out << ")(";
+  }
       
   writeOperand(I.getOperand(0));
 
@@ -995,6 +1078,10 @@
   }
 
   writeOperand(I.getOperand(1));
+
+  if (needsCast) {
+    Out << "))";
+  }
 }
 
 void CWriter::visitCastInst(CastInst &I) {
@@ -1118,6 +1205,8 @@
   } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Ptr)) {
     HasImplicitAddress = true;
     Ptr = CPR->getValue();         // Get to the global...
+  } else if (isDirectAlloca(Ptr)) {
+    HasImplicitAddress = true;
   }
 
   if (I == E) {





More information about the llvm-commits mailing list