summaryrefslogtreecommitdiffstats
path: root/lib/Target/MSIL/MSILWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/MSIL/MSILWriter.cpp')
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp184
1 files changed, 104 insertions, 80 deletions
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
index ee73c38..26d637b 100644
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ b/lib/Target/MSIL/MSILWriter.cpp
@@ -19,44 +19,35 @@
#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/Target/TargetRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/Passes.h"
+using namespace llvm;
-namespace {
+namespace llvm {
// 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 std::string &TT, const std::string &FS)
+ : TargetMachine(T) {}
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,
CodeGenOpt::Level OptLevel);
- // This class always works, but shouldn't be the default in most cases.
- static unsigned getModuleMatchQuality(const Module &M) { return 1; }
-
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const TargetData *getTargetData() const { return 0; }
};
}
-/// 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<MSILTarget> X("msil", "MSIL backend");
-
-// Force static initialization.
-extern "C" void LLVMInitializeMSILTarget() { }
+extern "C" void LLVMInitializeMSILTarget() {
+ // Register the target.
+ RegisterTargetMachine<MSILTarget> X(TheMSILTarget);
+}
bool MSILModule::runOnModule(Module &M) {
ModulePtr = &M;
@@ -239,8 +230,17 @@ bool MSILWriter::isZeroValue(const Value* V) {
std::string MSILWriter::getValueName(const Value* V) {
+ std::string Name;
+ if (const GlobalValue *GV = dyn_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+"'";
}
@@ -257,11 +257,20 @@ 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<GlobalValue>(V))
+ Name = Mang->getMangledName(GV);
+ else {
+ unsigned &No = AnonValueNumbers[V];
+ if (No == 0) No = ++NextAnonValueNumber;
+ Name = "tmp" + utostr(No);
+ }
+
+ return getLabelName(Name);
}
-std::string MSILWriter::getConvModopt(unsigned CallingConvID) {
+std::string MSILWriter::getConvModopt(CallingConv::ID CallingConvID) {
switch (CallingConvID) {
case CallingConv::C:
case CallingConv::Cold:
@@ -272,8 +281,8 @@ std::string MSILWriter::getConvModopt(unsigned CallingConvID) {
case CallingConv::X86_StdCall:
return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) ";
default:
- cerr << "CallingConvID = " << CallingConvID << '\n';
- assert(0 && "Unsupported calling convention");
+ errs() << "CallingConvID = " << CallingConvID << '\n';
+ llvm_unreachable("Unsupported calling convention");
}
return ""; // Not reached
}
@@ -318,8 +327,8 @@ std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) {
case Type::DoubleTyID:
return "float64 ";
default:
- cerr << "Type = " << *Ty << '\n';
- assert(0 && "Invalid primitive type");
+ errs() << "Type = " << *Ty << '\n';
+ llvm_unreachable("Invalid primitive type");
}
return ""; // Not reached
}
@@ -346,8 +355,8 @@ std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
return getArrayTypeName(Ty->getTypeID(),Ty);
return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
default:
- cerr << "Type = " << *Ty << '\n';
- assert(0 && "Invalid type in getTypeName()");
+ errs() << "Type = " << *Ty << '\n';
+ llvm_unreachable("Invalid type in getTypeName()");
}
return ""; // Not reached
}
@@ -390,8 +399,8 @@ std::string MSILWriter::getTypePostfix(const Type* Ty, bool Expand,
case Type::PointerTyID:
return "i"+utostr(TD->getTypeAllocSize(Ty));
default:
- cerr << "TypeID = " << Ty->getTypeID() << '\n';
- assert(0 && "Invalid type in TypeToPostfix()");
+ errs() << "TypeID = " << Ty->getTypeID() << '\n';
+ llvm_unreachable("Invalid type in TypeToPostfix()");
}
return ""; // Not reached
}
@@ -406,7 +415,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");
}
}
@@ -417,15 +426,15 @@ void MSILWriter::printPtrLoad(uint64_t N) {
printSimpleInstruction("ldc.i4",utostr(N).c_str());
// FIXME: Need overflow test?
if (!isUInt32(N)) {
- cerr << "Value = " << utostr(N) << '\n';
- assert(0 && "32-bit pointer overflowed");
+ errs() << "Value = " << utostr(N) << '\n';
+ 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");
}
}
@@ -460,8 +469,8 @@ void MSILWriter::printConstLoad(const Constant* C) {
// Undefined constant value = NULL.
printPtrLoad(0);
} else {
- cerr << "Constant = " << *C << '\n';
- assert(0 && "Invalid constant value");
+ errs() << "Constant = " << *C << '\n';
+ llvm_unreachable("Invalid constant value");
}
Out << '\n';
}
@@ -509,8 +518,8 @@ void MSILWriter::printValueLoad(const Value* V) {
printConstantExpr(cast<ConstantExpr>(V));
break;
default:
- cerr << "Value = " << *V << '\n';
- assert(0 && "Invalid value location");
+ errs() << "Value = " << *V << '\n';
+ llvm_unreachable("Invalid value location");
}
}
@@ -524,8 +533,8 @@ void MSILWriter::printValueSave(const Value* V) {
printSimpleInstruction("stloc",getValueName(V).c_str());
break;
default:
- cerr << "Value = " << *V << '\n';
- assert(0 && "Invalid value location");
+ errs() << "Value = " << *V << '\n';
+ llvm_unreachable("Invalid value location");
}
}
@@ -651,12 +660,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);
@@ -679,8 +695,8 @@ void MSILWriter::printCastInstruction(unsigned int Op, const Value* V,
// FIXME: meaning that ld*/st* instruction do not change data format.
break;
default:
- cerr << "Opcode = " << Op << '\n';
- assert(0 && "Invalid conversion instruction");
+ errs() << "Opcode = " << Op << '\n';
+ llvm_unreachable("Invalid conversion instruction");
}
}
@@ -770,8 +786,8 @@ void MSILWriter::printFunctionCall(const Value* FnVal,
else if (const InvokeInst* Invoke = dyn_cast<InvokeInst>(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<Function>(FnVal)) {
// Direct call.
@@ -804,7 +820,8 @@ void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) {
// Save as pointer type "void*"
printValueLoad(Inst->getOperand(1));
printSimpleInstruction("ldloca",Name.c_str());
- printIndirectSave(PointerType::getUnqual(IntegerType::get(8)));
+ printIndirectSave(PointerType::getUnqual(
+ IntegerType::get(Inst->getContext(), 8)));
break;
case Intrinsic::vaend:
// Close argument list handle.
@@ -818,8 +835,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");
}
}
@@ -877,12 +894,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");
}
}
@@ -976,7 +994,7 @@ void MSILWriter::printFCmpInstruction(unsigned Predicate, const Value* Left,
printSimpleInstruction("or");
break;
default:
- assert(0 && "Illegal FCmp predicate");
+ llvm_unreachable("Illegal FCmp predicate");
}
}
@@ -1024,7 +1042,8 @@ void MSILWriter::printVAArgInstruction(const VAArgInst* Inst) {
"instance typedref [mscorlib]System.ArgIterator::GetNextArg()");
printSimpleInstruction("refanyval","void*");
std::string Name =
- "ldind."+getTypePostfix(PointerType::getUnqual(IntegerType::get(8)),false);
+ "ldind."+getTypePostfix(PointerType::getUnqual(
+ IntegerType::get(Inst->getContext(), 8)),false);
printSimpleInstruction(Name.c_str());
}
@@ -1132,9 +1151,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:
@@ -1169,10 +1192,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\"");
@@ -1184,8 +1207,8 @@ void MSILWriter::printInstruction(const Instruction* Inst) {
printVAArgInstruction(cast<VAArgInst>(Inst));
break;
default:
- cerr << "Instruction = " << Inst->getName() << '\n';
- assert(0 && "Unsupported instruction");
+ errs() << "Instruction = " << Inst->getName() << '\n';
+ llvm_unreachable("Unsupported instruction");
}
}
@@ -1216,7 +1239,7 @@ void MSILWriter::printBasicBlock(const BasicBlock* BB) {
// Print instruction
printInstruction(Inst);
// Save result
- if (Inst->getType()!=Type::VoidTy) {
+ if (Inst->getType()!=Type::getVoidTy(BB->getContext())) {
// Do not save value after invoke, it done in "try" block
if (Inst->getOpcode()==Instruction::Invoke) continue;
printValueSave(Inst);
@@ -1245,7 +1268,7 @@ void MSILWriter::printLocalVariables(const Function& F) {
Ty = PointerType::getUnqual(AI->getAllocatedType());
Name = getValueName(AI);
Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
- } else if (I->getType()!=Type::VoidTy) {
+ } else if (I->getType()!=Type::getVoidTy(F.getContext())) {
// Operation result.
Ty = I->getType();
Name = getValueName(&*I);
@@ -1372,8 +1395,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");
}
}
@@ -1406,8 +1429,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");
}
}
}
@@ -1470,8 +1493,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
}
@@ -1528,12 +1551,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;
@@ -1555,8 +1578,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;
@@ -1595,17 +1618,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, CallingConv::C);
}
-const char* MSILWriter::getLibraryForSymbol(const char* Name, bool isFunction,
- unsigned CallingConv) {
+const char* MSILWriter::getLibraryForSymbol(const StringRef &Name,
+ bool isFunction,
+ CallingConv::ID CallingConv) {
// TODO: Read *.def file with function and libraries definitions.
return "MSVCRT.DLL";
}
@@ -1654,11 +1678,10 @@ void MSILWriter::printExternals() {
E = ModulePtr->global_end(); I!=E; ++I) {
if (!I->isDeclaration() || !I->hasDLLImportLinkage()) continue;
// Use "LoadLibrary"/"GetProcAddress" to recive variable address.
- std::string Label = "not_null$_"+utostr(getUniqID());
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());
}
@@ -1671,7 +1694,8 @@ 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,
CodeGenOpt::Level OptLevel)
{
OpenPOWER on IntegriCloud