X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FTarget%2FMSIL%2FMSILWriter.cpp;h=c3808d379eea9bed501e51584e21717987f28604;hb=ce63ffb52f249b62cdf2d250c128007b13f27e71;hp=077145b321a2fdf34faf4a0477a5e10e51549c64;hpb=9c0f146d50ccc3ba780d4854b8e14422430013ef;p=oota-llvm.git diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp index 077145b321a..c3808d379ee 100644 --- a/lib/Target/MSIL/MSILWriter.cpp +++ b/lib/Target/MSIL/MSILWriter.cpp @@ -19,23 +19,27 @@ #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" #include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/Passes.h" +using namespace MSIL; namespace { // TargetMachine for the MSIL 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, - CodeGenFileType FileType, bool Fast); + virtual bool addPassesToEmitWholeFile(PassManager &PM, + formatted_raw_ostream &Out, + CodeGenFileType FileType, + CodeGenOpt::Level OptLevel); // This class always works, but shouldn't be the default in most cases. static unsigned getModuleMatchQuality(const Module &M) { return 1; } @@ -44,15 +48,10 @@ 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; +static RegisterTarget X(TheMSILTarget, "msil", "MSIL backend"); -static RegisterTarget X("msil", "MSIL backend"); +// Force static initialization. +extern "C" void LLVMInitializeMSILTarget() { } bool MSILModule::runOnModule(Module &M) { ModulePtr = &M; @@ -93,6 +92,12 @@ char MSILWriter::ID = 0; bool MSILWriter::runOnFunction(Function &F) { if (F.isDeclaration()) return false; + + // Do not codegen any 'available_externally' functions at all, they have + // definitions outside the translation unit. + if (F.hasAvailableExternallyLinkage()) + return false; + LInfo = &getAnalysis(); printFunction(F); return false; @@ -229,8 +234,17 @@ bool MSILWriter::isZeroValue(const Value* V) { std::string MSILWriter::getValueName(const Value* V) { + std::string Name; + if (const GlobalValue *GV = dyn_cast(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+"'"; } @@ -247,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 = dyn_cast(V)) + Name = Mang->getMangledName(GV); + else { + unsigned &No = AnonValueNumbers[V]; + if (No == 0) No = ++NextAnonValueNumber; + Name = "tmp" + utostr(No); + } + + return getLabelName(Name); } @@ -263,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 } @@ -309,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 } @@ -337,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 } @@ -378,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 } @@ -396,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"); } } @@ -408,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"); } } @@ -451,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'; } @@ -500,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"); } } @@ -515,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"); } } @@ -641,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); @@ -670,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"); } } @@ -688,14 +718,14 @@ void MSILWriter::printGepInstruction(const Value* V, gep_type_iterator I, uint64_t FieldIndex = cast(IndexValue)->getZExtValue(); // Offset is the sum of all previous structure fields. for (uint64_t F = 0; FgetTypePaddedSize(StrucTy->getContainedType((unsigned)F)); + Size += TD->getTypeAllocSize(StrucTy->getContainedType((unsigned)F)); printPtrLoad(Size); printSimpleInstruction("add"); continue; } else if (const SequentialType* SeqTy = dyn_cast(*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)) { @@ -760,8 +790,8 @@ void MSILWriter::printFunctionCall(const Value* FnVal, else if (const InvokeInst* Invoke = dyn_cast(Inst)) Name = getConvModopt(Invoke->getCallingConv()); else { - cerr << "Instruction = " << Inst->getName() << '\n'; - assert(0 && "Need \"Invoke\" or \"Call\" instruction only"); + errs() << "Instruction = " << Inst->getName() << '\n'; + llvm_unreachable("Need \"Invoke\" or \"Call\" instruction only"); } if (const Function* F = dyn_cast(FnVal)) { // Direct call. @@ -808,8 +838,8 @@ void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) { printSimpleInstruction("cpobj","[mscorlib]System.ArgIterator"); break; default: - cerr << "Intrinsic ID = " << Inst->getIntrinsicID() << '\n'; - assert(0 && "Invalid intrinsic function"); + errs() << "Intrinsic ID = " << Inst->getIntrinsicID() << '\n'; + llvm_unreachable("Invalid intrinsic function"); } } @@ -867,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"); + errs() << "Predicate = " << Predicate << '\n'; + llvm_unreachable("Invalid icmp predicate"); } } @@ -966,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"); } } @@ -1020,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(Inst->getOperand(0))) { printPtrLoad(CInt->getZExtValue()*Size); @@ -1053,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: @@ -1119,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(Inst)->getDestTy(), + cast(Inst)->getSrcTy()); + break; case Instruction::Trunc: case Instruction::ZExt: - case Instruction::SExt: case Instruction::FPTrunc: case Instruction::FPExt: case Instruction::UIToFP: @@ -1156,10 +1194,10 @@ void MSILWriter::printInstruction(const Instruction* Inst) { printAllocaInstruction(cast(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\""); @@ -1171,8 +1209,8 @@ void MSILWriter::printInstruction(const Instruction* Inst) { printVAArgInstruction(cast(Inst)); break; default: - cerr << "Instruction = " << Inst->getName() << '\n'; - assert(0 && "Unsupported instruction"); + errs() << "Instruction = " << Inst->getName() << '\n'; + llvm_unreachable("Unsupported instruction"); } } @@ -1315,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: @@ -1356,8 +1397,8 @@ void MSILWriter::printConstantExpr(const ConstantExpr* CE) { printBinaryInstruction("shr",left,right); break; default: - cerr << "Expression = " << *CE << "\n"; - assert(0 && "Invalid constant expression"); + errs() << "Expression = " << *CE << "\n"; + llvm_unreachable("Invalid constant expression"); } } @@ -1390,8 +1431,8 @@ void MSILWriter::printStaticInitializerList() { postfix = "stind."+postfix; printSimpleInstruction(postfix.c_str()); } else { - cerr << "Constant = " << *I->constant << '\n'; - assert(0 && "Invalid static initializer"); + errs() << "Constant = " << *I->constant << '\n'; + llvm_unreachable("Invalid static initializer"); } } } @@ -1436,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"; } } @@ -1454,8 +1495,8 @@ unsigned int MSILWriter::getBitWidth(const Type* Ty) { case 64: return N; default: - cerr << "Bits = " << N << '\n'; - assert(0 && "Unsupported integer width"); + errs() << "Bits = " << N << '\n'; + llvm_unreachable("Unsupported integer width"); } return 0; // Not reached } @@ -1466,7 +1507,7 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) { const Type* Ty = C->getType(); // Print zero initialized constant. if (isa(C) || C->isNullValue()) { - TySize = TD->getTypePaddedSize(C->getType()); + TySize = TD->getTypeAllocSize(C->getType()); Offset += TySize; Out << "int8 (0) [" << TySize << "]"; return; @@ -1474,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(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(C); if (Ty->getTypeID() == Type::FloatTyID) Out << "int32 (" << @@ -1500,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(C)) { std::string name = getValueName(G); @@ -1512,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()"); + errs() << "TypeID = " << Ty->getTypeID() << '\n'; + llvm_unreachable("Invalid type in printStaticConstant()"); } // Increase offset. Offset += TySize; @@ -1539,8 +1580,8 @@ void MSILWriter::printStaticInitializer(const Constant* C, Out << getTypeName(C->getType()); break; default: - cerr << "Type = " << *C << "\n"; - assert(0 && "Invalid constant type"); + errs() << "Type = " << *C << "\n"; + llvm_unreachable("Invalid constant type"); } // Print initializer std::string label = Name; @@ -1579,17 +1620,18 @@ void MSILWriter::printGlobalVariables() { const char* MSILWriter::getLibraryName(const Function* F) { - return getLibraryForSymbol(F->getName().c_str(), true, F->getCallingConv()); + return getLibraryForSymbol(F->getName(), true, F->getCallingConv()); } const char* MSILWriter::getLibraryName(const GlobalVariable* GV) { - return getLibraryForSymbol(Mang->getValueName(GV).c_str(), false, 0); + return getLibraryForSymbol(Mang->getMangledName(GV), false, 0); } -const char* MSILWriter::getLibraryForSymbol(const char* Name, bool isFunction, - unsigned CallingConv) { +const char* MSILWriter::getLibraryForSymbol(const StringRef &Name, + bool isFunction, + unsigned CallingConv) { // TODO: Read *.def file with function and libraries definitions. return "MSVCRT.DLL"; } @@ -1642,7 +1684,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()); } @@ -1655,8 +1697,10 @@ void MSILWriter::printExternals() { // External Interface declaration //===----------------------------------------------------------------------===// -bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, raw_ostream &o, - CodeGenFileType FileType, bool Fast) +bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, + formatted_raw_ostream &o, + CodeGenFileType FileType, + CodeGenOpt::Level OptLevel) { if (FileType != TargetMachine::AssemblyFile) return true; MSILWriter* Writer = new MSILWriter(o);