diff options
author | Chris Lattner <sabre@nondot.org> | 2010-08-28 16:33:36 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-08-28 16:33:36 +0000 |
commit | 885b661e1004978f39cd1d74e586f193dfc0b0a6 (patch) | |
tree | a94f664646bc8d8463cf362ef07e4e7926c05a62 | |
parent | 9df0a0a8711596eaa3c7dd3413c0835ad99d3929 (diff) |
remove the MSIL backend. It isn't maintained, is buggy, has no testcases
and hasn't kept up with ToT. Approved by Anton.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112375 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | autoconf/configure.ac | 5 | ||||
-rwxr-xr-x | configure | 5 | ||||
-rw-r--r-- | docs/ReleaseNotes.html | 9 | ||||
-rw-r--r-- | lib/Target/MSIL/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/Target/MSIL/MSILWriter.cpp | 1706 | ||||
-rw-r--r-- | lib/Target/MSIL/MSILWriter.h | 258 | ||||
-rw-r--r-- | lib/Target/MSIL/Makefile | 16 | ||||
-rw-r--r-- | lib/Target/MSIL/README.TXT | 26 | ||||
-rw-r--r-- | lib/Target/MSIL/TargetInfo/CMakeLists.txt | 6 | ||||
-rw-r--r-- | lib/Target/MSIL/TargetInfo/MSILTargetInfo.cpp | 26 | ||||
-rw-r--r-- | lib/Target/MSIL/TargetInfo/Makefile | 15 |
11 files changed, 9 insertions, 2066 deletions
diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 0271386234..5a8a5f99fb 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -543,13 +543,13 @@ TARGETS_TO_BUILD="" AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets], [Build specific host targets: all or target1,target2,... Valid targets are: host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu, pic16, - xcore, msp430, systemz, blackfin, cbe, msil, and cpp (default=all)]),, + xcore, msp430, systemz, blackfin, cbe, and cpp (default=all)]),, enableval=all) if test "$enableval" = host-only ; then enableval=host fi case "$enableval" in - all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;; + all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze" ;; *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do case "$a_target" in x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;; @@ -566,7 +566,6 @@ case "$enableval" in systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;; blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;; cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;; - msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;; cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;; mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;; host) case "$llvm_cv_target_arch" in @@ -1414,7 +1414,7 @@ Optional Features: --enable-targets Build specific host targets: all or target1,target2,... Valid targets are: host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu, - pic16, xcore, msp430, systemz, blackfin, cbe, msil, + pic16, xcore, msp430, systemz, blackfin, cbe, and cpp (default=all) --enable-cbe-printf-a Enable C Backend output with hex floating point via %a (default is YES) @@ -4955,7 +4955,7 @@ if test "$enableval" = host-only ; then enableval=host fi case "$enableval" in - all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;; + all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze" ;; *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do case "$a_target" in x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;; @@ -4972,7 +4972,6 @@ case "$enableval" in systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;; blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;; cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;; - msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;; cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;; mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;; host) case "$llvm_cv_target_arch" in diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html index 3595735033..f9f492c263 100644 --- a/docs/ReleaseNotes.html +++ b/docs/ReleaseNotes.html @@ -68,7 +68,6 @@ Almost dead code. lib/Transforms/IPO/MergeFunctions.cpp => consider for 2.8. llvm/Analysis/PointerTracking.h => Edwin wants this, consider for 2.8. GEPSplitterPass - MSIL backend? --> @@ -77,6 +76,7 @@ Almost dead code. strong phi elim llvm.dbg.value: variable debug info for optimized code loop dependence analysis + TBAA --> <!-- for announcement email: @@ -489,8 +489,9 @@ on LLVM 2.7, this section lists some "gotchas" that you may run into upgrading from the previous release.</p> <ul> - -<li>.</li> +<li>MSIL Backend removed.</li> +<li>ABCD and SSI passes removed.</li> +<li>'Union' LLVM IR feature removed.</li> </ul> <p>In addition, many APIs have changed in this release. Some of the major LLVM @@ -575,7 +576,7 @@ components, please contact us on the <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list</a>.</p> <ul> -<li>The MSIL, Alpha, SPU, MIPS, PIC16, Blackfin, MSP430, SystemZ and MicroBlaze +<li>The Alpha, SPU, MIPS, PIC16, Blackfin, MSP430, SystemZ and MicroBlaze backends are experimental.</li> <li><tt>llc</tt> "<tt>-filetype=asm</tt>" (the default) is the only supported value for this option. XXX Update me</li> diff --git a/lib/Target/MSIL/CMakeLists.txt b/lib/Target/MSIL/CMakeLists.txt deleted file mode 100644 index b1d47ef05e..0000000000 --- a/lib/Target/MSIL/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_llvm_target(MSIL - MSILWriter.cpp - ) diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp deleted file mode 100644 index cc350e8a4f..0000000000 --- a/lib/Target/MSIL/MSILWriter.cpp +++ /dev/null @@ -1,1706 +0,0 @@ -//===-- MSILWriter.cpp - Library for converting LLVM code to MSIL ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This library converts LLVM code to MSIL code. -// -//===----------------------------------------------------------------------===// - -#include "MSILWriter.h" -#include "llvm/CallingConv.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Intrinsics.h" -#include "llvm/IntrinsicInst.h" -#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 llvm { - // TargetMachine for the MSIL - struct MSILTarget : public TargetMachine { - MSILTarget(const Target &T, const std::string &TT, const std::string &FS) - : TargetMachine(T) {} - - virtual bool addPassesToEmitFile(PassManagerBase &PM, - formatted_raw_ostream &Out, - CodeGenFileType FileType, - CodeGenOpt::Level OptLevel, - bool DisableVerify); - - virtual const TargetData *getTargetData() const { return 0; } - }; -} - -extern "C" void LLVMInitializeMSILTarget() { - // Register the target. - RegisterTargetMachine<MSILTarget> X(TheMSILTarget); -} - -bool MSILModule::runOnModule(Module &M) { - ModulePtr = &M; - TD = &getAnalysis<TargetData>(); - bool Changed = false; - // Find named types. - TypeSymbolTable& Table = M.getTypeSymbolTable(); - std::set<const Type *> Types = getAnalysis<FindUsedTypes>().getTypes(); - for (TypeSymbolTable::iterator I = Table.begin(), E = Table.end(); I!=E; ) { - if (!I->second->isStructTy() && !I->second->isOpaqueTy()) - Table.remove(I++); - else { - std::set<const Type *>::iterator T = Types.find(I->second); - if (T==Types.end()) - Table.remove(I++); - else { - Types.erase(T); - ++I; - } - } - } - // Find unnamed types. - unsigned RenameCounter = 0; - for (std::set<const Type *>::const_iterator I = Types.begin(), - E = Types.end(); I!=E; ++I) - if (const StructType *STy = dyn_cast<StructType>(*I)) { - while (ModulePtr->addTypeName("unnamed$"+utostr(RenameCounter), STy)) - ++RenameCounter; - Changed = true; - } - // Pointer for FunctionPass. - UsedTypes = &getAnalysis<FindUsedTypes>().getTypes(); - return Changed; -} - -char MSILModule::ID = 0; -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<LoopInfo>(); - printFunction(F); - return false; -} - - -bool MSILWriter::doInitialization(Module &M) { - ModulePtr = &M; - Out << ".assembly extern mscorlib {}\n"; - Out << ".assembly MSIL {}\n\n"; - Out << "// External\n"; - printExternals(); - Out << "// Declarations\n"; - printDeclarations(M.getTypeSymbolTable()); - Out << "// Definitions\n"; - printGlobalVariables(); - Out << "// Startup code\n"; - printModuleStartup(); - return false; -} - - -bool MSILWriter::doFinalization(Module &M) { - return false; -} - - -void MSILWriter::printModuleStartup() { - Out << - ".method static public int32 $MSIL_Startup() {\n" - "\t.entrypoint\n" - "\t.locals (native int i)\n" - "\t.locals (native int argc)\n" - "\t.locals (native int ptr)\n" - "\t.locals (void* argv)\n" - "\t.locals (string[] args)\n" - "\tcall\tstring[] [mscorlib]System.Environment::GetCommandLineArgs()\n" - "\tdup\n" - "\tstloc\targs\n" - "\tldlen\n" - "\tconv.i4\n" - "\tdup\n" - "\tstloc\targc\n"; - printPtrLoad(TD->getPointerSize()); - Out << - "\tmul\n" - "\tlocalloc\n" - "\tstloc\targv\n" - "\tldc.i4.0\n" - "\tstloc\ti\n" - "L_01:\n" - "\tldloc\ti\n" - "\tldloc\targc\n" - "\tceq\n" - "\tbrtrue\tL_02\n" - "\tldloc\targs\n" - "\tldloc\ti\n" - "\tldelem.ref\n" - "\tcall\tnative int [mscorlib]System.Runtime.InteropServices.Marshal::" - "StringToHGlobalAnsi(string)\n" - "\tstloc\tptr\n" - "\tldloc\targv\n" - "\tldloc\ti\n"; - printPtrLoad(TD->getPointerSize()); - Out << - "\tmul\n" - "\tadd\n" - "\tldloc\tptr\n" - "\tstind.i\n" - "\tldloc\ti\n" - "\tldc.i4.1\n" - "\tadd\n" - "\tstloc\ti\n" - "\tbr\tL_01\n" - "L_02:\n" - "\tcall void $MSIL_Init()\n"; - - // Call user 'main' function. - const Function* F = ModulePtr->getFunction("main"); - if (!F || F->isDeclaration()) { - Out << "\tldc.i4.0\n\tret\n}\n"; - return; - } - bool BadSig = true; - std::string Args(""); - Function::const_arg_iterator Arg1,Arg2; - - switch (F->arg_size()) { - case 0: - BadSig = false; - break; - case 1: - Arg1 = F->arg_begin(); - if (Arg1->getType()->isIntegerTy()) { - Out << "\tldloc\targc\n"; - Args = getTypeName(Arg1->getType()); - BadSig = false; - } - break; - case 2: - Arg1 = Arg2 = F->arg_begin(); ++Arg2; - if (Arg1->getType()->isIntegerTy() && - Arg2->getType()->getTypeID() == Type::PointerTyID) { - Out << "\tldloc\targc\n\tldloc\targv\n"; - Args = getTypeName(Arg1->getType())+","+getTypeName(Arg2->getType()); - BadSig = false; - } - break; - default: - BadSig = true; - } - - bool RetVoid = (F->getReturnType()->getTypeID() == Type::VoidTyID); - if (BadSig || (!F->getReturnType()->isIntegerTy() && !RetVoid)) { - Out << "\tldc.i4.0\n"; - } else { - Out << "\tcall\t" << getTypeName(F->getReturnType()) << - getConvModopt(F->getCallingConv()) << "main(" << Args << ")\n"; - if (RetVoid) - Out << "\tldc.i4.0\n"; - else - Out << "\tconv.i4\n"; - } - Out << "\tret\n}\n"; -} - -bool MSILWriter::isZeroValue(const Value* V) { - if (const Constant *C = dyn_cast<Constant>(V)) - return C->isNullValue(); - return false; -} - - -std::string MSILWriter::getValueName(const Value* V) { - std::string Name; - if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) - Name = GV->getName(); - else { - unsigned &No = AnonValueNumbers[V]; - if (No == 0) No = ++NextAnonValueNumber; - Name = "tmp" + utostr(No); - } - - // Name into the quotes allow control and space characters. - return "'"+Name+"'"; -} - - -std::string MSILWriter::getLabelName(const std::string& Name) { - if (Name.find('.')!=std::string::npos) { - std::string Tmp(Name); - // Replace unaccepable characters in the label name. - for (std::string::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) - if (*I=='.') *I = '@'; - return Tmp; - } - return Name; -} - - -std::string MSILWriter::getLabelName(const Value* V) { - std::string Name; - if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) - Name = GV->getName(); - else { - unsigned &No = AnonValueNumbers[V]; - if (No == 0) No = ++NextAnonValueNumber; - Name = "tmp" + utostr(No); - } - - return getLabelName(Name); -} - - -std::string MSILWriter::getConvModopt(CallingConv::ID CallingConvID) { - switch (CallingConvID) { - case CallingConv::C: - case CallingConv::Cold: - case CallingConv::Fast: - return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) "; - case CallingConv::X86_FastCall: - return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvFastcall) "; - case CallingConv::X86_StdCall: - return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) "; - case CallingConv::X86_ThisCall: - return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) "; - default: - errs() << "CallingConvID = " << CallingConvID << '\n'; - llvm_unreachable("Unsupported calling convention"); - } - return ""; // Not reached -} - - -std::string MSILWriter::getArrayTypeName(Type::TypeID TyID, const Type* Ty) { - std::string Tmp = ""; - const Type* ElemTy = Ty; - assert(Ty->getTypeID()==TyID && "Invalid type passed"); - // Walk trought array element types. - for (;;) { - // Multidimensional array. - if (ElemTy->getTypeID()==TyID) { - if (const ArrayType* ATy = dyn_cast<ArrayType>(ElemTy)) - Tmp += utostr(ATy->getNumElements()); - else if (const VectorType* VTy = dyn_cast<VectorType>(ElemTy)) - Tmp += utostr(VTy->getNumElements()); - ElemTy = cast<SequentialType>(ElemTy)->getElementType(); - } - // Base element type found. - if (ElemTy->getTypeID()!=TyID) break; - Tmp += ","; - } - return getTypeName(ElemTy, false, true)+"["+Tmp+"]"; -} - - -std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) { - unsigned NumBits = 0; - switch (Ty->getTypeID()) { - case Type::VoidTyID: - return "void "; - case Type::IntegerTyID: - NumBits = getBitWidth(Ty); - if(NumBits==1) - return "bool "; - if (!isSigned) - return "unsigned int"+utostr(NumBits)+" "; - return "int"+utostr(NumBits)+" "; - case Type::FloatTyID: - return "float32 "; - case Type::DoubleTyID: - return "float64 "; - default: - errs() << "Type = " << *Ty << '\n'; - llvm_unreachable("Invalid primitive type"); - } - return ""; // Not reached -} - - -std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned, - bool isNested) { - if (Ty->isPrimitiveType() || Ty->isIntegerTy()) - return getPrimitiveTypeName(Ty,isSigned); - // FIXME: "OpaqueType" support - switch (Ty->getTypeID()) { - case Type::PointerTyID: - return "void* "; - case Type::StructTyID: - if (isNested) - return ModulePtr->getTypeName(Ty); - return "valuetype '"+ModulePtr->getTypeName(Ty)+"' "; - case Type::ArrayTyID: - if (isNested) - return getArrayTypeName(Ty->getTypeID(),Ty); - return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' "; - case Type::VectorTyID: - if (isNested) - return getArrayTypeName(Ty->getTypeID(),Ty); - return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' "; - default: - errs() << "Type = " << *Ty << '\n'; - llvm_unreachable("Invalid type in getTypeName()"); - } - return ""; // Not reached -} - - -MSILWriter::ValueType MSILWriter::getValueLocation(const Value* V) { - // Function argument - if (isa<Argument>(V)) - return ArgumentVT; - // Function - else if (const Function* F = dyn_cast<Function>(V)) - return F->hasLocalLinkage() ? InternalVT : GlobalVT; - // Variable - else if (const GlobalVariable* G = dyn_cast<GlobalVariable>(V)) - return G->hasLocalLinkage() ? InternalVT : GlobalVT; - // Constant - else if (isa<Constant>(V)) - return isa<ConstantExpr>(V) ? ConstExprVT : ConstVT; - // Local variable - return LocalVT; -} - - -std::string MSILWriter::getTypePostfix(const Type* Ty, bool Expand, - bool isSigned) { - unsigned NumBits = 0; - switch (Ty->getTypeID()) { - // Integer constant, expanding for stack operations. - case Type::IntegerTyID: - NumBits = getBitWidth(Ty); - // Expand integer value to "int32" or "int64". - if (Expand) return (NumBits<=32 ? "i4" : "i8"); - if (NumBits==1) return "i1"; - return (isSigned ? "i" : "u")+utostr(NumBits/8); - // Float constant. - case Type::FloatTyID: - return "r4"; - case Type::DoubleTyID: - return "r8"; - case Type::PointerTyID: - return "i"+utostr(TD->getTypeAllocSize(Ty)); - default: - errs() << "TypeID = " << Ty->getTypeID() << '\n'; - llvm_unreachable("Invalid type in TypeToPostfix()"); - } - return ""; // Not reached -} - - -void MSILWriter::printConvToPtr() { - switch (ModulePtr->getPointerSize()) { - case Module::Pointer32: - printSimpleInstruction("conv.u4"); - break; - case Module::Pointer64: - printSimpleInstruction("conv.u8"); - break; - default: - llvm_unreachable("Module use not supporting pointer size"); - } -} - - -void MSILWriter::printPtrLoad(uint64_t N) { - switch (ModulePtr->getPointerSize()) { - case Module::Pointer32: - printSimpleInstruction("ldc.i4",utostr(N).c_str()); - // FIXME: Need overflow test? - if (!isUInt<32>(N)) { - errs() << "Value = " << utostr(N) << '\n'; - llvm_unreachable("32-bit pointer overflowed"); - } - break; - case Module::Pointer64: - printSimpleInstruction("ldc.i8",utostr(N).c_str()); - break; - default: - llvm_unreachable("Module use not supporting pointer size"); - } -} - - -void MSILWriter::printValuePtrLoad(const Value* V) { - printValueLoad(V); - printConvToPtr(); -} - - -void MSILWriter::printConstLoad(const Constant* C) { - if (const ConstantInt* CInt = dyn_cast<ConstantInt>(C)) { - // Integer constant - Out << "\tldc." << getTypePostfix(C->getType(),true) << '\t'; - if (CInt->isMinValue(true)) - Out << CInt->getSExtValue(); - else - Out << CInt->getZExtValue(); - } else if (const ConstantFP* FP = dyn_cast<ConstantFP>(C)) { - // Float constant - uint64_t X; - unsigned Size; - if (FP->getType()->getTypeID()==Type::FloatTyID) { - X = (uint32_t)FP->getValueAPF().bitcastToAPInt().getZExtValue(); - Size = 4; - } else { - X = FP->getValueAPF().bitcastToAPInt().getZExtValue(); - Size = 8; - } - Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')'; - } else if (isa<UndefValue>(C)) { - // Undefined constant value = NULL. - printPtrLoad(0); - } else { - errs() << "Constant = " << *C << '\n'; - llvm_unreachable("Invalid constant value"); - } - Out << '\n'; -} - - -void MSILWriter::printValueLoad(const Value* V) { - MSILWriter::ValueType Location = getValueLocation(V); - switch (Location) { - // Global variable or function address. - case GlobalVT: - case InternalVT: - if (const Function* F = dyn_cast<Function>(V)) { - std::string Name = getConvModopt(F->getCallingConv())+getValueName(F); - printSimpleInstruction("ldftn", - getCallSignature(F->getFunctionType(),NULL,Name).c_str()); - } else { - std::string Tmp; - const Type* ElemTy = cast<PointerType>(V->getType())->getElementType(); - if (Location==GlobalVT && cast<GlobalVariable>(V)->hasDLLImportLinkage()) { - Tmp = "void* "+getValueName(V); - printSimpleInstruction("ldsfld",Tmp.c_str()); - } else { - Tmp = getTypeName(ElemTy)+getValueName(V); - printSimpleInstruction("ldsflda",Tmp.c_str()); - } - } - break; - // Function argument. - case ArgumentVT: - printSimpleInstruction("ldarg",getValueName(V).c_str()); - break; - // Local function variable. - case LocalVT: - printSimpleInstruction("ldloc",getValueName(V).c_str()); - break; - // Constant value. - case ConstVT: - if (isa<ConstantPointerNull>(V)) - printPtrLoad(0); - else - printConstLoad(cast<Constant>(V)); - break; - // Constant expression. - case ConstExprVT: - printConstantExpr(cast<ConstantExpr>(V)); - break; - default: - errs() << "Value = " << *V << '\n'; - llvm_unreachable("Invalid value location"); - } -} - - -void MSILWriter::printValueSave(const Value* V) { - switch (getValueLocation(V)) { - case ArgumentVT: - printSimpleInstruction("starg",getValueName(V).c_str()); - break; - case LocalVT: - printSimpleInstruction("stloc",getValueName(V).c_str()); - break; - default: - errs() << "Value = " << *V << '\n'; - llvm_unreachable("Invalid value location"); - } -} - - -void MSILWriter::printBinaryInstruction(const char* Name, const Value* Left, - const Value* Right) { - printValueLoad(Left); - printValueLoad(Right); - Out << '\t' << Name << '\n'; -} - - -void MSILWriter::printSimpleInstruction(const char* Inst, const char* Operand) { - if(Operand) - Out << '\t' << Inst << '\t' << Operand << '\n'; - else - Out << '\t' << Inst << '\n'; -} - - -void MSILWriter::printPHICopy(const BasicBlock* Src, const BasicBlock* Dst) { - for (BasicBlock::const_iterator I = Dst->begin(); isa<PHINode>(I); ++I) { - const PHINode* Phi = cast<PHINode>(I); - const Value* Val = Phi->getIncomingValueForBlock(Src); - if (isa<UndefValue>(Val)) continue; - printValueLoad(Val); - printValueSave(Phi); - } -} - - -void MSILWriter::printBranchToBlock(const BasicBlock* CurrBB, - const BasicBlock* TrueBB, - const BasicBlock* FalseBB) { - if (TrueBB==FalseBB) { - // "TrueBB" and "FalseBB" destination equals - printPHICopy(CurrBB,TrueBB); - printSimpleInstruction("pop"); - printSimpleInstruction("br",getLabelName(TrueBB).c_str()); - } else if (FalseBB==NULL) { - // If "FalseBB" not used the jump have condition - printPHICopy(CurrBB,TrueBB); - printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str()); - } else if (TrueBB==NULL) { - // If "TrueBB" not used the jump is unconditional - printPHICopy(CurrBB,FalseBB); - printSimpleInstruction("br",getLabelName(FalseBB).c_str()); - } else { - // Copy PHI instructions for each block - std::string TmpLabel; - // Print PHI instructions for "TrueBB" - if (isa<PHINode>(TrueBB->begin())) { - TmpLabel = getLabelName(TrueBB)+"$phi_"+utostr(getUniqID()); - printSimpleInstruction("brtrue",TmpLabel.c_str()); - } else { - printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str()); - } - // Print PHI instructions for "FalseBB" - if (isa<PHINode>(FalseBB->begin())) { - printPHICopy(CurrBB,FalseBB); - printSimpleInstruction("br",getLabelName(FalseBB).c_str()); - } else { - printSimpleInstruction("br",getLabelName(FalseBB).c_str()); - } - if (isa<PHINode>(TrueBB->begin())) { - // Handle "TrueBB" PHI Copy - Out << TmpLabel << ":\n"; - printPHICopy(CurrBB,TrueBB); - printSimpleInstruction("br",getLabelName(TrueBB).c_str()); - } - } -} - - -void MSILWriter::printBranchInstruction(const BranchInst* Inst) { - if (Inst->isUnconditional()) { - printBranchToBlock(Inst->getParent(),NULL,Inst->getSuccessor(0)); - } else { - printValueLoad(Inst->getCondition()); - printBranchToBlock(Inst->getParent(),Inst->getSuccessor(0), - Inst->getSuccessor(1)); - } -} - - -void MSILWriter::printSelectInstruction(const Value* Cond, const Value* VTrue, - const Value* VFalse) { - std::string TmpLabel = std::string("select$true_")+utostr(getUniqID()); - printValueLoad(VTrue); - printValueLoad(Cond); - printSimpleInstruction("brtrue",TmpLabel.c_str()); - printSimpleInstruction("pop"); - printValueLoad(VFalse); - Out << TmpLabel << ":\n"; -} - - -void MSILWriter::printIndirectLoad(const Value* V) { - const Type* Ty = V->getType(); - printValueLoad(V); - if (const PointerType* P = dyn_cast<PointerType>(Ty)) - Ty = P->getElementType(); - std::string Tmp = "ldind."+getTypePostfix(Ty, false); - printSimpleInstruction(Tmp.c_str()); -} - - -void MSILWriter::printIndirectSave(const Value* Ptr, const Value* Val) { - printValueLoad(Ptr); - printValueLoad(Val); - printIndirectSave(Val->getType()); -} - - -void MSILWriter::printIndirectSave(const Type* Ty) { - // Instruction need signed postfix for any type. - std::string postfix = getTypePostfix(Ty, false); - if (*postfix.begin()=='u') *postfix.begin() = 'i'; - postfix = "stind."+postfix; - printSimpleInstruction(postfix.c_str()); -} - - -void MSILWriter::printCastInstruction(unsigned int Op, const Value* V, - 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); - printSimpleInstruction(Tmp.c_str()); - break; - // Unsigned - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::UIToFP: - case Instruction::Trunc: - case Instruction::ZExt: - case Instruction::FPToUI: - case Instruction::PtrToInt: - case Instruction::IntToPtr: - Tmp = "conv."+getTypePostfix(Ty,false); - printSimpleInstruction(Tmp.c_str()); - break; - // Do nothing - case Instruction::BitCast: - // FIXME: meaning that ld*/st* instruction do not change data format. - break; - default: - errs() << "Opcode = " << Op << '\n'; - llvm_unreachable("Invalid conversion instruction"); - } -} - - -void MSILWriter::printGepInstruction(const Value* V, gep_type_iterator I, - gep_type_iterator E) { - unsigned Size; - // Load address - printValuePtrLoad(V); - // Calculate element offset. - for (; I!=E; ++I){ - Size = 0; - const Value* IndexValue = I.getOperand(); - if (const StructType* StrucTy = dyn_cast<StructType>(*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->getTypeAllocSize(StrucTy->getContainedType((unsigned)F)); - printPtrLoad(Size); - printSimpleInstruction("add"); - continue; - } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(*I)) { - Size = TD->getTypeAllocSize(SeqTy->getElementType()); - } else { - Size = TD->getTypeAllocSize(*I); - } - // Add offset of current element to stack top. - if (!isZeroValue(IndexValue)) { - // Constant optimization. - if (const ConstantInt* C = dyn_cast<ConstantInt>(IndexValue)) { - if (C->getValue().isNegative()) { - printPtrLoad(C->getValue().abs().getZExtValue()*Size); - printSimpleInstruction("sub"); - continue; - } else - printPtrLoad(C->getZExtValue()*Size); - } else { - printPtrLoad(Size); - printValuePtrLoad(IndexValue); - printSimpleInstruction("mul"); - } - printSimpleInstruction("add"); - } - } -} - - -std::string MSILWriter::getCallSignature(const FunctionType* Ty, - const Instruction* Inst, - std::string Name) { - std::string Tmp(""); - if (Ty->isVarArg()) Tmp += "vararg "; - // Name and return type. - Tmp += getTypeName(Ty->getReturnType())+Name+"("; - // Function argument type list. - unsigned NumParams = Ty->getNumParams(); - for (unsigned I = 0; I!=NumParams; ++I) { - if (I!=0) Tmp += ","; - Tmp += getTypeName(Ty->getParamType(I)); - } - // CLR needs to know the exact amount of parameters received by vararg - // function, because caller cleans the stack. - if (Ty->isVarArg() && Inst) { - // Origin to function arguments in "CallInst" or "InvokeInst". - unsigned Org = isa<InvokeInst>(Inst) ? 3 : 1; - // Print variable argument types. - unsigned NumOperands = Inst->getNumOperands()-Org; - if (NumParams<NumOperands) { - if (NumParams!=0) Tmp += ", "; - Tmp += "... , "; - for (unsigned J = NumParams; J!=NumOperands; ++J) { - if (J!=NumParams) Tmp += ", "; - Tmp += getTypeName(Inst->getOperand(J+Org)->getType()); - } - } - } - return Tmp+")"; -} - - -void MSILWriter::printFunctionCall(const Value* FnVal, - const Instruction* Inst) { - // Get function calling convention. - std::string Name = ""; - if (const CallInst* Call = dyn_cast<CallInst>(Inst)) - Name = getConvModopt(Call->getCallingConv()); - else if (const InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) - Name = getConvModopt(Invoke->getCallingConv()); - else { - errs() << "Instruction = " << Inst->getName() << '\n'; - llvm_unreachable("Need \"Invoke\" or \"Call\" instruction only"); - } - if (const Function* F = dyn_cast<Function>(FnVal)) { - // Direct call. - Name += getValueName(F); - printSimpleInstruction("call", - getCallSignature(F->getFunctionType(),Inst,Name).c_str()); - } else { - // Indirect function call. - const PointerType* PTy = cast<PointerType>(FnVal->getType()); - const FunctionType* FTy = cast<FunctionType>(PTy->getElementType()); - // Load function address. - printValueLoad(FnVal); - printSimpleInstruction("calli",getCallSignature(FTy,Inst,Name).c_str()); - } -} - - -void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) { - std::string Name; - switch (Inst->getIntrinsicID()) { - case Intrinsic::vastart: - Name = getValueName(Inst->getArgOperand(0)); - Name.insert(Name.length()-1,"$valist"); - // Obtain the argument handle. - printSimpleInstruction("ldloca",Name.c_str()); - printSimpleInstruction("arglist"); - printSimpleInstruction("call", - "instance void [mscorlib]System.ArgIterator::.ctor" - "(valuetype [mscorlib]System.RuntimeArgumentHandle)"); - // Save as pointer type "void*" - printValueLoad(Inst->getArgOperand(0)); - printSimpleInstruction("ldloca",Name.c_str()); - printIndirectSave(PointerType::getUnqual( - IntegerType::get(Inst->getContext(), 8))); - break; - case Intrinsic::vaend: - // Close argument list handle. - printIndirectLoad(Inst->getArgOperand(0)); - printSimpleInstruction("call","instance void [mscorlib]System.ArgIterator::End()"); - break; - case Intrinsic::vacopy: - // Copy "ArgIterator" valuetype. - printIndirectLoad(Inst->getArgOperand(0)); - printIndirectLoad(Inst->getArgOperand(1)); - printSimpleInstruction("cpobj","[mscorlib]System.ArgIterator"); - b |