Don't try to set an EFLAGS operand to dead if no instruction was created.
[oota-llvm.git] / lib / Target / MSIL / MSILWriter.cpp
index 5d6740bd1e8f2e7d39a1aedcefd084b3406b0bfe..e8b4d24c11ca192c4b5b25296db1ed6d18d818d3 100644 (file)
@@ -1,9 +1,9 @@
 //===-- MSILWriter.cpp - Library for converting LLVM code to MSIL ---------===//
 //
-//                    The LLVM Compiler Infrastructure
+//                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Roman Samoilov and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -16,7 +16,6 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/IntrinsicInst.h"
-#include "llvm/ParameterAttributes.h"
 #include "llvm/TypeSymbolTable.h"
 #include "llvm/Analysis/ConstantsScanner.h"
 #include "llvm/Support/CallSite.h"
@@ -24,6 +23,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/CodeGen/Passes.h"
 
 namespace {
   // TargetMachine for the MSIL 
@@ -34,7 +34,7 @@ namespace {
       : DataLayout(&M) {}
 
     virtual bool WantsWholeFile() const { return true; }
-    virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
+    virtual bool addPassesToEmitWholeFile(PassManager &PM, raw_ostream &Out,
                                          CodeGenFileType FileType, bool Fast);
 
     // This class always works, but shouldn't be the default in most cases.
@@ -44,8 +44,15 @@ namespace {
   };
 }
 
+/// MSILTargetMachineModule - Note that this is used on hosts that
+/// cannot link in a library unless there are references into the
+/// library.  In particular, it seems that it is not possible to get
+/// things to work on Win32 without this.  Though it is unused, do not
+/// remove it.
+extern "C" int MSILTargetMachineModule;
+int MSILTargetMachineModule = 0;
 
-RegisterTarget<MSILTarget> X("msil", "  MSIL backend");
+static RegisterTarget<MSILTarget> X("msil", "MSIL backend");
 
 bool MSILModule::runOnModule(Module &M) {
   ModulePtr = &M;
@@ -201,7 +208,7 @@ void MSILWriter::printModuleStartup() {
   }
 
   bool RetVoid = (F->getReturnType()->getTypeID() == Type::VoidTyID);
-  if (BadSig || !F->getReturnType()->isInteger() && !RetVoid) {
+  if (BadSig || (!F->getReturnType()->isInteger() && !RetVoid)) {
     Out << "\tldc.i4.0\n";
   } else {
     Out << "\tcall\t" << getTypeName(F->getReturnType()) <<
@@ -258,6 +265,7 @@ std::string MSILWriter::getConvModopt(unsigned CallingConvID) {
     cerr << "CallingConvID = " << CallingConvID << '\n';
     assert(0 && "Unsupported calling convention");
   }
+  return ""; // Not reached
 }
 
 
@@ -303,6 +311,7 @@ std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) {
     cerr << "Type = " << *Ty << '\n';
     assert(0 && "Invalid primitive type");
   }
+  return ""; // Not reached
 }
 
 
@@ -330,6 +339,7 @@ std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
     cerr << "Type = " << *Ty << '\n';
     assert(0 && "Invalid type in getTypeName()");
   }
+  return ""; // Not reached
 }
 
 
@@ -339,10 +349,10 @@ MSILWriter::ValueType MSILWriter::getValueLocation(const Value* V) {
     return ArgumentVT;
   // Function
   else if (const Function* F = dyn_cast<Function>(V))
-    return F->hasInternalLinkage() ? InternalVT : GlobalVT;
+    return F->hasLocalLinkage() ? InternalVT : GlobalVT;
   // Variable
   else if (const GlobalVariable* G = dyn_cast<GlobalVariable>(V))
-    return G->hasInternalLinkage() ? InternalVT : GlobalVT;
+    return G->hasLocalLinkage() ? InternalVT : GlobalVT;
   // Constant
   else if (isa<Constant>(V))
     return isa<ConstantExpr>(V) ? ConstExprVT : ConstVT;
@@ -368,11 +378,12 @@ std::string MSILWriter::getTypePostfix(const Type* Ty, bool Expand,
   case Type::DoubleTyID:
     return "r8";
   case Type::PointerTyID:
-    return "i"+utostr(TD->getTypeSize(Ty));
+    return "i"+utostr(TD->getTypePaddedSize(Ty));
   default:
     cerr << "TypeID = " << Ty->getTypeID() << '\n';
     assert(0 && "Invalid type in TypeToPostfix()");
   }
+  return ""; // Not reached
 }
 
 
@@ -428,10 +439,10 @@ void MSILWriter::printConstLoad(const Constant* C) {
     uint64_t X;
     unsigned Size;
     if (FP->getType()->getTypeID()==Type::FloatTyID) {
-      X = (uint32_t)FP->getValueAPF().convertToAPInt().getZExtValue();
+      X = (uint32_t)FP->getValueAPF().bitcastToAPInt().getZExtValue();
       Size = 4;  
     } else {
-      X = FP->getValueAPF().convertToAPInt().getZExtValue();
+      X = FP->getValueAPF().bitcastToAPInt().getZExtValue();
       Size = 8;  
     }
     Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')';
@@ -677,14 +688,14 @@ void MSILWriter::printGepInstruction(const Value* V, gep_type_iterator I,
       uint64_t FieldIndex = cast<ConstantInt>(IndexValue)->getZExtValue();
       // Offset is the sum of all previous structure fields.
       for (uint64_t F = 0; F<FieldIndex; ++F)
-        Size += TD->getTypeSize(StrucTy->getContainedType((unsigned)F));
+        Size += TD->getTypePaddedSize(StrucTy->getContainedType((unsigned)F));
       printPtrLoad(Size);
       printSimpleInstruction("add");
       continue;
     } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(*I)) {
-      Size = TD->getTypeSize(SeqTy->getElementType());
+      Size = TD->getTypePaddedSize(SeqTy->getElementType());
     } else {
-      Size = TD->getTypeSize(*I);
+      Size = TD->getTypePaddedSize(*I);
     }
     // Add offset of current element to stack top.
     if (!isZeroValue(IndexValue)) {
@@ -783,7 +794,7 @@ void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) {
     // Save as pointer type "void*"
     printValueLoad(Inst->getOperand(1));
     printSimpleInstruction("ldloca",Name.c_str());
-    printIndirectSave(PointerType::get(IntegerType::get(8)));
+    printIndirectSave(PointerType::getUnqual(IntegerType::get(8)));
     break;
   case Intrinsic::vaend:
     // Close argument list handle.
@@ -1002,13 +1013,14 @@ void MSILWriter::printVAArgInstruction(const VAArgInst* Inst) {
   printSimpleInstruction("call",
     "instance typedref [mscorlib]System.ArgIterator::GetNextArg()");
   printSimpleInstruction("refanyval","void*");
-  std::string Name = "ldind."+getTypePostfix(PointerType::get(IntegerType::get(8)),false);
+  std::string Name = 
+    "ldind."+getTypePostfix(PointerType::getUnqual(IntegerType::get(8)),false);
   printSimpleInstruction(Name.c_str());
 }
 
 
 void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) {
-  uint64_t Size = TD->getTypeSize(Inst->getAllocatedType());
+  uint64_t Size = TD->getTypePaddedSize(Inst->getAllocatedType());
   // Constant optimization.
   if (const ConstantInt* CInt = dyn_cast<ConstantInt>(Inst->getOperand(0))) {
     printPtrLoad(CInt->getZExtValue()*Size);
@@ -1185,7 +1197,7 @@ void MSILWriter::printBasicBlock(const BasicBlock* BB) {
   for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
     const Instruction* Inst = I;
     // Comment llvm original instruction
-    Out << "\n//" << *Inst << "\n";
+    // Out << "\n//" << *Inst << "\n";
     // Do not handle PHI instruction in current block
     if (Inst->getOpcode()==Instruction::PHI) continue;
     // Print instruction
@@ -1217,7 +1229,7 @@ void MSILWriter::printLocalVariables(const Function& F) {
     const AllocaInst* AI = dyn_cast<AllocaInst>(&*I);
     if (AI && !isa<GlobalVariable>(AI)) {
       // Local variable allocation.
-      Ty = PointerType::get(AI->getAllocatedType());
+      Ty = PointerType::getUnqual(AI->getAllocatedType());
       Name = getValueName(AI);
       Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
     } else if (I->getType()!=Type::VoidTy) {
@@ -1361,8 +1373,8 @@ void MSILWriter::printStaticInitializerList() {
     for (std::vector<StaticInitializer>::const_iterator I = InitList.begin(),
          E = InitList.end(); I!=E; ++I) {
       if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(I->constant)) {
-        Out << "\n// Init " << getValueName(VarI->first) << ", offset " <<
-          utostr(I->offset) << ", type "<< *I->constant->getType() << "\n\n";
+        // Out << "\n// Init " << getValueName(VarI->first) << ", offset " <<
+        //  utostr(I->offset) << ", type "<< *I->constant->getType() << "\n\n";
         // Load variable address
         printValueLoad(VarI->first);
         // Add offset
@@ -1387,11 +1399,9 @@ void MSILWriter::printStaticInitializerList() {
 
 
 void MSILWriter::printFunction(const Function& F) {
-  const FunctionType* FTy = F.getFunctionType();
-  const ParamAttrsList *Attrs = FTy->getParamAttrs();
-  bool isSigned = Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt);
+  bool isSigned = F.paramHasAttr(0, Attribute::SExt);
   Out << "\n.method static ";
-  Out << (F.hasInternalLinkage() ? "private " : "public ");
+  Out << (F.hasLocalLinkage() ? "private " : "public ");
   if (F.isVarArg()) Out << "vararg ";
   Out << getTypeName(F.getReturnType(),isSigned) << 
     getConvModopt(F.getCallingConv()) << getValueName(&F) << '\n';
@@ -1400,7 +1410,7 @@ void MSILWriter::printFunction(const Function& F) {
   unsigned ArgIdx = 1;
   for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I!=E;
        ++I, ++ArgIdx) {
-    isSigned = Attrs && Attrs->paramHasAttr(ArgIdx, ParamAttr::SExt);
+    isSigned = F.paramHasAttr(ArgIdx, Attribute::SExt);
     if (I!=F.arg_begin()) Out << ", ";
     Out << getTypeName(I->getType(),isSigned) << getValueName(I);
   }
@@ -1426,7 +1436,8 @@ void MSILWriter::printDeclarations(const TypeSymbolTable& ST) {
     // Print not duplicated type
     if (Printed.insert(Ty).second) {
       Out << ".class value explicit ansi sealed '" << Name << "'";
-      Out << " { .pack " << 1 << " .size " << TD->getTypeSize(Ty) << " }\n\n";
+      Out << " { .pack " << 1 << " .size " << TD->getTypePaddedSize(Ty);
+      Out << " }\n\n";
     }
   }
 }
@@ -1446,6 +1457,7 @@ unsigned int MSILWriter::getBitWidth(const Type* Ty) {
     cerr << "Bits = " << N << '\n';
     assert(0 && "Unsupported integer width");
   }
+  return 0; // Not reached
 }
 
 
@@ -1454,7 +1466,7 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
   const Type* Ty = C->getType();
   // Print zero initialized constant.
   if (isa<ConstantAggregateZero>(C) || C->isNullValue()) {
-    TySize = TD->getTypeSize(C->getType());
+    TySize = TD->getTypePaddedSize(C->getType());
     Offset += TySize;
     Out << "int8 (0) [" << TySize << "]";
     return;
@@ -1462,21 +1474,21 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
   // Print constant initializer
   switch (Ty->getTypeID()) {
   case Type::IntegerTyID: {
-    TySize = TD->getTypeSize(Ty);
+    TySize = TD->getTypePaddedSize(Ty);
     const ConstantInt* Int = cast<ConstantInt>(C);
     Out << getPrimitiveTypeName(Ty,true) << "(" << Int->getSExtValue() << ")";
     break;
   }
   case Type::FloatTyID:
   case Type::DoubleTyID: {
-    TySize = TD->getTypeSize(Ty);
+    TySize = TD->getTypePaddedSize(Ty);
     const ConstantFP* FP = cast<ConstantFP>(C);
     if (Ty->getTypeID() == Type::FloatTyID)
       Out << "int32 (" << 
-        (uint32_t)FP->getValueAPF().convertToAPInt().getZExtValue() << ')';
+        (uint32_t)FP->getValueAPF().bitcastToAPInt().getZExtValue() << ')';
     else
       Out << "int64 (" << 
-        FP->getValueAPF().convertToAPInt().getZExtValue() << ')';
+        FP->getValueAPF().bitcastToAPInt().getZExtValue() << ')';
     break;
   }
   case Type::ArrayTyID:
@@ -1488,7 +1500,7 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
     }
     break;
   case Type::PointerTyID:
-    TySize = TD->getTypeSize(C->getType());
+    TySize = TD->getTypePaddedSize(C->getType());
     // Initialize with global variable address
     if (const GlobalVariable *G = dyn_cast<GlobalVariable>(C)) {
       std::string name = getValueName(G);
@@ -1588,7 +1600,7 @@ void MSILWriter::printExternals() {
   // Functions.
   for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) {
     // Skip intrisics
-    if (I->getIntrinsicID()) continue;
+    if (I->isIntrinsic()) continue;
     if (I->isDeclaration()) {
       const Function* F = I; 
       std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
@@ -1640,20 +1652,21 @@ void MSILWriter::printExternals() {
 
 
 //===----------------------------------------------------------------------===//
-//                      External Interface declaration
+//                      External Interface declaration
 //===----------------------------------------------------------------------===//
 
-bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, std::ostream &o,
+bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, raw_ostream &o,
                                           CodeGenFileType FileType, bool Fast)
 {
   if (FileType != TargetMachine::AssemblyFile) return true;
   MSILWriter* Writer = new MSILWriter(o);
-  PM.add(createLowerGCPass());
+  PM.add(createGCLoweringPass());
   PM.add(createLowerAllocationsPass(true));
   // FIXME: Handle switch trougth native IL instruction "switch"
   PM.add(createLowerSwitchPass());
   PM.add(createCFGSimplificationPass());
   PM.add(new MSILModule(Writer->UsedTypes,Writer->TD));
   PM.add(Writer);
+  PM.add(createGCInfoDeleter());
   return false;
 }