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

Reid Spencer reid at x10sys.com
Sun Nov 26 17:06:24 PST 2006



Changes in directory llvm/lib/Target/CBackend:

Writer.cpp updated: 1.282 -> 1.283
---
Log message:

For PR950: http://llvm.org/PR950 :
The long awaited CAST patch. This introduces 12 new instructions into LLVM
to replace the cast instruction. Corresponding changes throughout LLVM are
provided. This passes llvm-test, llvm/test, and SPEC CPUINT2000 with the
exception of 175.vpr which fails only on a slight floating point output
difference.


---
Diffs of the changes:  (+123 -28)

 Writer.cpp |  151 +++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 123 insertions(+), 28 deletions(-)


Index: llvm/lib/Target/CBackend/Writer.cpp
diff -u llvm/lib/Target/CBackend/Writer.cpp:1.282 llvm/lib/Target/CBackend/Writer.cpp:1.283
--- llvm/lib/Target/CBackend/Writer.cpp:1.282	Wed Nov 15 12:00:10 2006
+++ llvm/lib/Target/CBackend/Writer.cpp	Sun Nov 26 19:05:10 2006
@@ -137,6 +137,7 @@
     void printBasicBlock(BasicBlock *BB);
     void printLoop(Loop *L);
 
+    void printCast(unsigned opcode, const Type *SrcTy, const Type *DstTy);
     void printConstant(Constant *CPV);
     void printConstantWithCast(Constant *CPV, unsigned Opcode);
     bool printConstExprCast(const ConstantExpr *CE);
@@ -560,15 +561,76 @@
 #endif
 }
 
+/// Print out the casting for a cast operation. This does the double casting
+/// necessary for conversion to the destination type, if necessary. 
+/// @returns true if a closing paren is necessary
+/// @brief Print a cast
+void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) {
+  Out << '(';
+  printType(Out, DstTy);
+  Out << ')';
+  switch (opc) {
+    case Instruction::UIToFP:
+    case Instruction::ZExt:
+      if (SrcTy->isSigned()) {
+        Out << '(';
+        printType(Out, SrcTy->getUnsignedVersion());
+        Out << ')';
+      }
+      break;
+    case Instruction::SIToFP:
+    case Instruction::SExt:
+      if (SrcTy->isUnsigned()) {
+        Out << '(';
+        printType(Out, SrcTy->getSignedVersion());
+        Out << ')';
+      }
+      break;
+    case Instruction::IntToPtr:
+    case Instruction::PtrToInt:
+        // Avoid "cast to pointer from integer of different size" warnings
+        Out << "(unsigned long)";
+        break;
+    case Instruction::Trunc:
+    case Instruction::BitCast:
+    case Instruction::FPExt:
+    case Instruction::FPTrunc:
+    case Instruction::FPToSI:
+    case Instruction::FPToUI:
+    default:
+      break;
+  }
+}
+
 // printConstant - The LLVM Constant to C Constant converter.
 void CWriter::printConstant(Constant *CPV) {
   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
     switch (CE->getOpcode()) {
-    case Instruction::Cast:
-      Out << "((";
-      printType(Out, CPV->getType());
-      Out << ')';
+    case Instruction::Trunc:
+    case Instruction::ZExt:
+    case Instruction::SExt:
+    case Instruction::FPTrunc:
+    case Instruction::FPExt:
+    case Instruction::UIToFP:
+    case Instruction::SIToFP:
+    case Instruction::FPToUI:
+    case Instruction::FPToSI:
+    case Instruction::PtrToInt:
+    case Instruction::IntToPtr:
+    case Instruction::BitCast:
+      Out << "(";
+      printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType());
+      if (CE->getOpcode() == Instruction::SExt &&
+          CE->getOperand(0)->getType() == Type::BoolTy) {
+        // Make sure we really sext from bool here by subtracting from 0
+        Out << "0-";
+      }
       printConstant(CE->getOperand(0));
+      if (CE->getOpcode() == Instruction::Trunc && 
+          CE->getType() == Type::BoolTy) {
+        // Make sure we really truncate to bool here by anding with 1
+        Out << "&1u";
+      }
       Out << ')';
       return;
 
@@ -829,14 +891,31 @@
 // care of detecting that case and printing the cast for the ConstantExpr.
 bool CWriter::printConstExprCast(const ConstantExpr* CE) {
   bool NeedsExplicitCast = false;
-  const Type* Ty = CE->getOperand(0)->getType();
+  const Type *Ty = CE->getOperand(0)->getType();
   switch (CE->getOpcode()) {
   case Instruction::LShr:
   case Instruction::URem: 
-  case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
+  case Instruction::UDiv: 
+    NeedsExplicitCast = Ty->isSigned(); break;
   case Instruction::AShr:
   case Instruction::SRem: 
-  case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
+  case Instruction::SDiv: 
+    NeedsExplicitCast = Ty->isUnsigned(); break;
+  case Instruction::ZExt:
+  case Instruction::SExt:
+  case Instruction::Trunc:
+  case Instruction::FPTrunc:
+  case Instruction::FPExt:
+  case Instruction::UIToFP:
+  case Instruction::SIToFP:
+  case Instruction::FPToUI:
+  case Instruction::FPToSI:
+  case Instruction::PtrToInt:
+  case Instruction::IntToPtr:
+  case Instruction::BitCast:
+    Ty = CE->getType();
+    NeedsExplicitCast = true;
+    break;
   default: break;
   }
   if (NeedsExplicitCast) {
@@ -860,7 +939,8 @@
 
   // Based on the Opcode for which this Constant is being written, determine
   // the new type to which the operand should be casted by setting the value
-  // of OpTy. If we change OpTy, also set shouldCast to true.
+  // of OpTy. If we change OpTy, also set shouldCast to true so it gets
+  // casted below.
   switch (Opcode) {
     default:
       // for most instructions, it doesn't matter
@@ -885,7 +965,7 @@
       break;
   }
 
-  // Write out the casted constnat if we should, otherwise just write the
+  // Write out the casted constant if we should, otherwise just write the
   // operand.
   if (shouldCast) {
     Out << "((";
@@ -918,7 +998,7 @@
 
 void CWriter::writeOperand(Value *Operand) {
   if (isa<GlobalVariable>(Operand) || isDirectAlloca(Operand))
-    Out << "(&";  // Global variables are references as their addresses by llvm
+    Out << "(&";  // Global variables are referenced as their addresses by llvm
 
   writeOperandInternal(Operand);
 
@@ -932,14 +1012,31 @@
 // for the Instruction.
 bool CWriter::writeInstructionCast(const Instruction &I) {
   bool NeedsExplicitCast = false;
-  const Type* Ty = I.getOperand(0)->getType();
+  const Type *Ty = I.getOperand(0)->getType();
   switch (I.getOpcode()) {
   case Instruction::LShr:
   case Instruction::URem: 
-  case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
+  case Instruction::UDiv: 
+    NeedsExplicitCast = Ty->isSigned(); break;
   case Instruction::AShr:
   case Instruction::SRem: 
-  case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
+  case Instruction::SDiv: 
+    NeedsExplicitCast = Ty->isUnsigned(); break;
+  case Instruction::ZExt:
+  case Instruction::SExt:
+  case Instruction::Trunc:
+  case Instruction::FPTrunc:
+  case Instruction::FPExt:
+  case Instruction::UIToFP:
+  case Instruction::SIToFP:
+  case Instruction::FPToUI:
+  case Instruction::FPToSI:
+  case Instruction::PtrToInt:
+  case Instruction::IntToPtr:
+  case Instruction::BitCast:
+    Ty = I.getType();
+    NeedsExplicitCast = true;
+    break;
   default: break;
   }
   if (NeedsExplicitCast) {
@@ -1136,7 +1233,7 @@
         return;  // Found a null terminator, exit printing.
       Constant *FP = CS->getOperand(1);
       if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
-        if (CE->getOpcode() == Instruction::Cast)
+        if (CE->isCast())
           FP = CE->getOperand(0);
       if (Function *F = dyn_cast<Function>(FP))
         StaticTors.insert(F);
@@ -1854,22 +1951,20 @@
 }
 
 void CWriter::visitCastInst(CastInst &I) {
-  if (I.getType() == Type::BoolTy) {
-    Out << '(';
-    writeOperand(I.getOperand(0));
-    Out << " != 0)";
-    return;
-  }
+  const Type *DstTy = I.getType();
+  const Type *SrcTy = I.getOperand(0)->getType();
   Out << '(';
-  printType(Out, I.getType());
-  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
-    Out << "(long)";
+  printCast(I.getOpcode(), SrcTy, DstTy);
+  if (I.getOpcode() == Instruction::SExt && SrcTy == Type::BoolTy) {
+    // Make sure we really get a sext from bool by subtracing the bool from 0
+    Out << "0-";
   }
-
   writeOperand(I.getOperand(0));
+  if (I.getOpcode() == Instruction::Trunc && DstTy == Type::BoolTy) {
+    // Make sure we really get a trunc to bool by anding the operand with 1 
+    Out << "&1u";
+  }
+  Out << ')';
 }
 
 void CWriter::visitSelectInst(SelectInst &I) {
@@ -2076,7 +2171,7 @@
     // match exactly.
     //
     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Callee))
-      if (CE->getOpcode() == Instruction::Cast)
+      if (CE->isCast())
         if (Function *RF = dyn_cast<Function>(CE->getOperand(0))) {
           NeedsCast = true;
           Callee = RF;






More information about the llvm-commits mailing list