Kill off <TARGET>MachineModule variables, and <TARGETASMPRINTER>ForceLink
[oota-llvm.git] / lib / Target / MSIL / MSILWriter.cpp
index 8d9a1ea7edc7399bb1be382191d69c0a5da40c4f..8bd3c7bc22df918b98f0ff6700707b1211350602 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/TypeSymbolTable.h"
 #include "llvm/Analysis/ConstantsScanner.h"
 #include "llvm/Support/CallSite.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Transforms/Scalar.h"
@@ -30,13 +31,14 @@ namespace {
   struct VISIBILITY_HIDDEN MSILTarget : public TargetMachine {
     const TargetData DataLayout;       // Calculates type size & alignment
 
-    MSILTarget(const Module &M, const std::string &FS)
-      : DataLayout(&M) {}
+    MSILTarget(const Target &T, const Module &M, const std::string &FS)
+      : TargetMachine(T), DataLayout(&M) {}
 
     virtual bool WantsWholeFile() const { return true; }
-    virtual bool addPassesToEmitWholeFile(PassManager &PM, raw_ostream &Out,
+    virtual bool addPassesToEmitWholeFile(PassManager &PM,
+                                          formatted_raw_ostream &Out,
                                           CodeGenFileType FileType,
-                                          unsigned OptLevel);
+                                          CodeGenOpt::Level OptLevel);
 
     // This class always works, but shouldn't be the default in most cases.
     static unsigned getModuleMatchQuality(const Module &M) { return 1; }
@@ -45,15 +47,11 @@ 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;
+extern Target TheMSILTarget;
+static RegisterTarget<MSILTarget> X(TheMSILTarget, "msil", "MSIL backend");
 
-static RegisterTarget<MSILTarget> X("msil", "MSIL backend");
+// Force static initialization.
+extern "C" void LLVMInitializeMSILTarget() { }
 
 bool MSILModule::runOnModule(Module &M) {
   ModulePtr = &M;
@@ -236,8 +234,17 @@ bool MSILWriter::isZeroValue(const Value* V) {
 
 
 std::string MSILWriter::getValueName(const Value* V) {
+  std::string Name;
+  if (const GlobalValue *GV = cast<GlobalValue>(V))
+    Name = Mang->getMangledName(GV);
+  else {
+    unsigned &No = AnonValueNumbers[V];
+    if (No == 0) No = ++NextAnonValueNumber;
+    Name = "tmp" + utostr(No);
+  }
+  
   // Name into the quotes allow control and space characters.
-  return "'"+Mang->getValueName(V)+"'";
+  return "'"+Name+"'";
 }
 
 
@@ -254,7 +261,16 @@ std::string MSILWriter::getLabelName(const std::string& Name) {
 
 
 std::string MSILWriter::getLabelName(const Value* V) {
-  return getLabelName(Mang->getValueName(V));
+  std::string Name;
+  if (const GlobalValue *GV = cast<GlobalValue>(V))
+    Name = Mang->getMangledName(GV);
+  else {
+    unsigned &No = AnonValueNumbers[V];
+    if (No == 0) No = ++NextAnonValueNumber;
+    Name = "tmp" + utostr(No);
+  }
+  
+  return getLabelName(Name);
 }
 
 
@@ -270,7 +286,7 @@ std::string MSILWriter::getConvModopt(unsigned CallingConvID) {
     return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) ";
   default:
     cerr << "CallingConvID = " << CallingConvID << '\n';
-    assert(0 && "Unsupported calling convention");
+    llvm_unreachable("Unsupported calling convention");
   }
   return ""; // Not reached
 }
@@ -316,7 +332,7 @@ std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) {
     return "float64 "; 
   default:
     cerr << "Type = " << *Ty << '\n';
-    assert(0 && "Invalid primitive type");
+    llvm_unreachable("Invalid primitive type");
   }
   return ""; // Not reached
 }
@@ -344,7 +360,7 @@ std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
     return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
   default:
     cerr << "Type = " << *Ty << '\n';
-    assert(0 && "Invalid type in getTypeName()");
+    llvm_unreachable("Invalid type in getTypeName()");
   }
   return ""; // Not reached
 }
@@ -385,10 +401,10 @@ std::string MSILWriter::getTypePostfix(const Type* Ty, bool Expand,
   case Type::DoubleTyID:
     return "r8";
   case Type::PointerTyID:
-    return "i"+utostr(TD->getTypePaddedSize(Ty));
+    return "i"+utostr(TD->getTypeAllocSize(Ty));
   default:
     cerr << "TypeID = " << Ty->getTypeID() << '\n';
-    assert(0 && "Invalid type in TypeToPostfix()");
+    llvm_unreachable("Invalid type in TypeToPostfix()");
   }
   return ""; // Not reached
 }
@@ -403,7 +419,7 @@ void MSILWriter::printConvToPtr() {
     printSimpleInstruction("conv.u8");
     break;
   default:
-    assert(0 && "Module use not supporting pointer size");
+    llvm_unreachable("Module use not supporting pointer size");
   }
 }
 
@@ -415,14 +431,14 @@ void MSILWriter::printPtrLoad(uint64_t N) {
     // FIXME: Need overflow test?
     if (!isUInt32(N)) {
       cerr << "Value = " << utostr(N) << '\n';
-      assert(0 && "32-bit pointer overflowed");
+      llvm_unreachable("32-bit pointer overflowed");
     }
     break;
   case Module::Pointer64:
     printSimpleInstruction("ldc.i8",utostr(N).c_str());
     break;
   default:
-    assert(0 && "Module use not supporting pointer size");
+    llvm_unreachable("Module use not supporting pointer size");
   }
 }
 
@@ -458,7 +474,7 @@ void MSILWriter::printConstLoad(const Constant* C) {
     printPtrLoad(0);
   } else {
     cerr << "Constant = " << *C << '\n';
-    assert(0 && "Invalid constant value");
+    llvm_unreachable("Invalid constant value");
   }
   Out << '\n';
 }
@@ -507,7 +523,7 @@ void MSILWriter::printValueLoad(const Value* V) {
     break;
   default:
     cerr << "Value = " << *V << '\n';
-    assert(0 && "Invalid value location");
+    llvm_unreachable("Invalid value location");
   }
 }
 
@@ -522,7 +538,7 @@ void MSILWriter::printValueSave(const Value* V) {
     break;
   default:
     cerr << "Value  = " << *V << '\n';
-    assert(0 && "Invalid value location");
+    llvm_unreachable("Invalid value location");
   }
 }
 
@@ -648,12 +664,19 @@ void MSILWriter::printIndirectSave(const Type* Ty) {
 
 
 void MSILWriter::printCastInstruction(unsigned int Op, const Value* V,
-                                      const Type* Ty) {
+                                      const Type* Ty, const Type* SrcTy) {
   std::string Tmp("");
   printValueLoad(V);
   switch (Op) {
   // Signed
   case Instruction::SExt:
+    // If sign extending int, convert first from unsigned to signed
+    // with the same bit size - because otherwise we will loose the sign.
+    if (SrcTy) {
+      Tmp = "conv."+getTypePostfix(SrcTy,false,true);
+      printSimpleInstruction(Tmp.c_str());
+    }
+    // FALLTHROUGH
   case Instruction::SIToFP:
   case Instruction::FPToSI:
     Tmp = "conv."+getTypePostfix(Ty,false,true);
@@ -677,7 +700,7 @@ void MSILWriter::printCastInstruction(unsigned int Op, const Value* V,
     break;
   default:
     cerr << "Opcode = " << Op << '\n';
-    assert(0 && "Invalid conversion instruction");
+    llvm_unreachable("Invalid conversion instruction");
   }
 }
 
@@ -695,14 +718,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->getTypePaddedSize(StrucTy->getContainedType((unsigned)F));
+        Size += TD->getTypeAllocSize(StrucTy->getContainedType((unsigned)F));
       printPtrLoad(Size);
       printSimpleInstruction("add");
       continue;
     } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(*I)) {
-      Size = TD->getTypePaddedSize(SeqTy->getElementType());
+      Size = TD->getTypeAllocSize(SeqTy->getElementType());
     } else {
-      Size = TD->getTypePaddedSize(*I);
+      Size = TD->getTypeAllocSize(*I);
     }
     // Add offset of current element to stack top.
     if (!isZeroValue(IndexValue)) {
@@ -768,7 +791,7 @@ void MSILWriter::printFunctionCall(const Value* FnVal,
     Name = getConvModopt(Invoke->getCallingConv());
   else {
     cerr << "Instruction = " << Inst->getName() << '\n';
-    assert(0 && "Need \"Invoke\" or \"Call\" instruction only");
+    llvm_unreachable("Need \"Invoke\" or \"Call\" instruction only");
   }
   if (const Function* F = dyn_cast<Function>(FnVal)) {
     // Direct call.
@@ -816,7 +839,7 @@ void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) {
     break;        
   default:
     cerr << "Intrinsic ID = " << Inst->getIntrinsicID() << '\n';
-    assert(0 && "Invalid intrinsic function");
+    llvm_unreachable("Invalid intrinsic function");
   }
 }
 
@@ -874,12 +897,13 @@ void MSILWriter::printICmpInstruction(unsigned Predicate, const Value* Left,
     break;
   case ICmpInst::ICMP_UGT:
     printBinaryInstruction("cgt.un",Left,Right);
+    break;
   case ICmpInst::ICMP_SGT:
     printBinaryInstruction("cgt",Left,Right);
     break;
   default:
     cerr << "Predicate = " << Predicate << '\n';
-    assert(0 && "Invalid icmp predicate");
+    llvm_unreachable("Invalid icmp predicate");
   }
 }
 
@@ -973,7 +997,7 @@ void MSILWriter::printFCmpInstruction(unsigned Predicate, const Value* Left,
     printSimpleInstruction("or");
     break;
   default:
-    assert(0 && "Illegal FCmp predicate");
+    llvm_unreachable("Illegal FCmp predicate");
   }
 }
 
@@ -1027,7 +1051,7 @@ void MSILWriter::printVAArgInstruction(const VAArgInst* Inst) {
 
 
 void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) {
-  uint64_t Size = TD->getTypePaddedSize(Inst->getAllocatedType());
+  uint64_t Size = TD->getTypeAllocSize(Inst->getAllocatedType());
   // Constant optimization.
   if (const ConstantInt* CInt = dyn_cast<ConstantInt>(Inst->getOperand(0))) {
     printPtrLoad(CInt->getZExtValue()*Size);
@@ -1060,12 +1084,15 @@ void MSILWriter::printInstruction(const Instruction* Inst) {
     break;
   // Binary
   case Instruction::Add:
+  case Instruction::FAdd:
     printBinaryInstruction("add",Left,Right);
     break;
   case Instruction::Sub:
+  case Instruction::FSub:
     printBinaryInstruction("sub",Left,Right);
     break;
-  case Instruction::Mul:  
+  case Instruction::Mul:
+  case Instruction::FMul:
     printBinaryInstruction("mul",Left,Right);
     break;
   case Instruction::UDiv:
@@ -1126,9 +1153,13 @@ void MSILWriter::printInstruction(const Instruction* Inst) {
   case Instruction::Store:
     printIndirectSave(Inst->getOperand(1), Inst->getOperand(0));
     break;
+  case Instruction::SExt:
+    printCastInstruction(Inst->getOpcode(),Left,
+                         cast<CastInst>(Inst)->getDestTy(),
+                         cast<CastInst>(Inst)->getSrcTy());
+    break;
   case Instruction::Trunc:
   case Instruction::ZExt:
-  case Instruction::SExt:
   case Instruction::FPTrunc:
   case Instruction::FPExt:
   case Instruction::UIToFP:
@@ -1163,10 +1194,10 @@ void MSILWriter::printInstruction(const Instruction* Inst) {
     printAllocaInstruction(cast<AllocaInst>(Inst));
     break;
   case Instruction::Malloc:
-    assert(0 && "LowerAllocationsPass used");
+    llvm_unreachable("LowerAllocationsPass used");
     break;
   case Instruction::Free:
-    assert(0 && "LowerAllocationsPass used");
+    llvm_unreachable("LowerAllocationsPass used");
     break;
   case Instruction::Unreachable:
     printSimpleInstruction("ldstr", "\"Unreachable instruction\"");
@@ -1179,7 +1210,7 @@ void MSILWriter::printInstruction(const Instruction* Inst) {
     break;
   default:
     cerr << "Instruction = " << Inst->getName() << '\n';
-    assert(0 && "Unsupported instruction");
+    llvm_unreachable("Unsupported instruction");
   }
 }
 
@@ -1322,12 +1353,15 @@ void MSILWriter::printConstantExpr(const ConstantExpr* CE) {
     printSelectInstruction(CE->getOperand(0),CE->getOperand(1),CE->getOperand(2));
     break;
   case Instruction::Add:
+  case Instruction::FAdd:
     printBinaryInstruction("add",left,right);
     break;
   case Instruction::Sub:
+  case Instruction::FSub:
     printBinaryInstruction("sub",left,right);
     break;
   case Instruction::Mul:
+  case Instruction::FMul:
     printBinaryInstruction("mul",left,right);
     break;
   case Instruction::UDiv:
@@ -1364,7 +1398,7 @@ void MSILWriter::printConstantExpr(const ConstantExpr* CE) {
     break;
   default:
     cerr << "Expression = " << *CE << "\n";
-    assert(0 && "Invalid constant expression");
+    llvm_unreachable("Invalid constant expression");
   }
 }
 
@@ -1398,7 +1432,7 @@ void MSILWriter::printStaticInitializerList() {
         printSimpleInstruction(postfix.c_str());
       } else {
         cerr << "Constant = " << *I->constant << '\n';
-        assert(0 && "Invalid static initializer");
+        llvm_unreachable("Invalid static initializer");
       }
     }
   }
@@ -1443,7 +1477,7 @@ 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->getTypePaddedSize(Ty);
+      Out << " { .pack " << 1 << " .size " << TD->getTypeAllocSize(Ty);
       Out << " }\n\n";
     }
   }
@@ -1462,7 +1496,7 @@ unsigned int MSILWriter::getBitWidth(const Type* Ty) {
     return N;
   default:
     cerr << "Bits = " << N << '\n';
-    assert(0 && "Unsupported integer width");
+    llvm_unreachable("Unsupported integer width");
   }
   return 0; // Not reached
 }
@@ -1473,7 +1507,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->getTypePaddedSize(C->getType());
+    TySize = TD->getTypeAllocSize(C->getType());
     Offset += TySize;
     Out << "int8 (0) [" << TySize << "]";
     return;
@@ -1481,14 +1515,14 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
   // Print constant initializer
   switch (Ty->getTypeID()) {
   case Type::IntegerTyID: {
-    TySize = TD->getTypePaddedSize(Ty);
+    TySize = TD->getTypeAllocSize(Ty);
     const ConstantInt* Int = cast<ConstantInt>(C);
     Out << getPrimitiveTypeName(Ty,true) << "(" << Int->getSExtValue() << ")";
     break;
   }
   case Type::FloatTyID:
   case Type::DoubleTyID: {
-    TySize = TD->getTypePaddedSize(Ty);
+    TySize = TD->getTypeAllocSize(Ty);
     const ConstantFP* FP = cast<ConstantFP>(C);
     if (Ty->getTypeID() == Type::FloatTyID)
       Out << "int32 (" << 
@@ -1507,7 +1541,7 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
     }
     break;
   case Type::PointerTyID:
-    TySize = TD->getTypePaddedSize(C->getType());
+    TySize = TD->getTypeAllocSize(C->getType());
     // Initialize with global variable address
     if (const GlobalVariable *G = dyn_cast<GlobalVariable>(C)) {
       std::string name = getValueName(G);
@@ -1519,12 +1553,12 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
       // Null pointer initialization
       if (TySize==4) Out << "int32 (0)";
       else if (TySize==8) Out << "int64 (0)";
-      else assert(0 && "Invalid pointer size");
+      else llvm_unreachable("Invalid pointer size");
     }
     break;
   default:
     cerr << "TypeID = " << Ty->getTypeID() << '\n';
-    assert(0 && "Invalid type in printStaticConstant()");
+    llvm_unreachable("Invalid type in printStaticConstant()");
   }
   // Increase offset.
   Offset += TySize;
@@ -1547,7 +1581,7 @@ void MSILWriter::printStaticInitializer(const Constant* C,
     break;
   default:
     cerr << "Type = " << *C << "\n";
-    assert(0 && "Invalid constant type");
+    llvm_unreachable("Invalid constant type");
   }
   // Print initializer
   std::string label = Name;
@@ -1591,7 +1625,7 @@ const char* MSILWriter::getLibraryName(const Function* F) {
 
 
 const char* MSILWriter::getLibraryName(const GlobalVariable* GV) {
-  return getLibraryForSymbol(Mang->getValueName(GV).c_str(), false, 0);
+  return getLibraryForSymbol(Mang->getMangledName(GV).c_str(), false, 0);
 }
 
 
@@ -1649,7 +1683,7 @@ void MSILWriter::printExternals() {
     std::string Tmp = getTypeName(I->getType())+getValueName(&*I);
     printSimpleInstruction("ldsflda",Tmp.c_str());
     Out << "\tldstr\t\"" << getLibraryName(&*I) << "\"\n";
-    Out << "\tldstr\t\"" << Mang->getValueName(&*I) << "\"\n";
+    Out << "\tldstr\t\"" << Mang->getMangledName(&*I) << "\"\n";
     printSimpleInstruction("call","void* $MSIL_Import(string,string)");
     printIndirectSave(I->getType());
   }
@@ -1662,9 +1696,10 @@ void MSILWriter::printExternals() {
 //                      External Interface declaration
 //===----------------------------------------------------------------------===//
 
-bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, raw_ostream &o,
+bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM,
+                                          formatted_raw_ostream &o,
                                           CodeGenFileType FileType,
-                                          unsigned OptLevel)
+                                          CodeGenOpt::Level OptLevel)
 {
   if (FileType != TargetMachine::AssemblyFile) return true;
   MSILWriter* Writer = new MSILWriter(o);