diff options
Diffstat (limited to 'lib/Target/CBackend')
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 383 | ||||
-rw-r--r-- | lib/Target/CBackend/CTargetMachine.h | 17 | ||||
-rw-r--r-- | lib/Target/CBackend/Makefile | 3 | ||||
-rw-r--r-- | lib/Target/CBackend/TargetInfo/CBackendTargetInfo.cpp | 19 | ||||
-rw-r--r-- | lib/Target/CBackend/TargetInfo/CMakeLists.txt | 6 | ||||
-rw-r--r-- | lib/Target/CBackend/TargetInfo/Makefile | 15 |
6 files changed, 282 insertions, 161 deletions
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 294c6d3..fe63edf 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -24,43 +24,36 @@ #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" #include "llvm/InlineAsm.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Target/TargetMachineRegistry.h" -#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/MathExtras.h" +#include "llvm/System/Host.h" #include "llvm/Config/config.h" #include <algorithm> #include <sstream> using namespace llvm; -/// CBackendTargetMachineModule - 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 CBackendTargetMachineModule; -int CBackendTargetMachineModule = 0; - -// Register the target. -static RegisterTarget<CTargetMachine> X("c", "C backend"); - -// Force static initialization. -extern "C" void LLVMInitializeCBackendTarget() { } +extern "C" void LLVMInitializeCBackendTarget() { + // Register the target. + RegisterTargetMachine<CTargetMachine> X(TheCBackendTarget); +} namespace { /// CBackendNameAllUsedStructsAndMergeFunctions - This pass inserts names for @@ -88,12 +81,12 @@ namespace { /// CWriter - This class is the main chunk of code that converts an LLVM /// module to a C translation unit. class CWriter : public FunctionPass, public InstVisitor<CWriter> { - raw_ostream &Out; + formatted_raw_ostream &Out; IntrinsicLowering *IL; Mangler *Mang; LoopInfo *LI; const Module *TheModule; - const TargetAsmInfo* TAsm; + const MCAsmInfo* TAsm; const TargetData* TD; std::map<const Type *, std::string> TypeNames; std::map<const ConstantFP *, unsigned> FPConstantMap; @@ -101,12 +94,14 @@ namespace { std::set<const Argument*> ByValParams; unsigned FPCounter; unsigned OpaqueCounter; + DenseMap<const Value*, unsigned> AnonValueNumbers; + unsigned NextAnonValueNumber; public: static char ID; - explicit CWriter(raw_ostream &o) + explicit CWriter(formatted_raw_ostream &o) : FunctionPass(&ID), Out(o), IL(0), Mang(0), LI(0), - TheModule(0), TAsm(0), TD(0), OpaqueCounter(0) { + TheModule(0), TAsm(0), TD(0), OpaqueCounter(0), NextAnonValueNumber(0) { FPCounter = 0; } @@ -149,24 +144,26 @@ namespace { return false; } - raw_ostream &printType(raw_ostream &Out, const Type *Ty, - bool isSigned = false, - const std::string &VariableName = "", - bool IgnoreName = false, - const AttrListPtr &PAL = AttrListPtr()); + raw_ostream &printType(formatted_raw_ostream &Out, + const Type *Ty, + bool isSigned = false, + const std::string &VariableName = "", + bool IgnoreName = false, + const AttrListPtr &PAL = AttrListPtr()); std::ostream &printType(std::ostream &Out, const Type *Ty, bool isSigned = false, const std::string &VariableName = "", bool IgnoreName = false, const AttrListPtr &PAL = AttrListPtr()); - raw_ostream &printSimpleType(raw_ostream &Out, const Type *Ty, - bool isSigned, - const std::string &NameSoFar = ""); + raw_ostream &printSimpleType(formatted_raw_ostream &Out, + const Type *Ty, + bool isSigned, + const std::string &NameSoFar = ""); std::ostream &printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned, const std::string &NameSoFar = ""); - void printStructReturnPointerFunctionType(raw_ostream &Out, + void printStructReturnPointerFunctionType(formatted_raw_ostream &Out, const AttrListPtr &PAL, const PointerType *Ty); @@ -239,7 +236,7 @@ namespace { // Must be an expression, must be used exactly once. If it is dead, we // emit it inline where it would go. - if (I.getType() == Type::VoidTy || !I.hasOneUse() || + if (I.getType() == Type::getVoidTy(I.getContext()) || !I.hasOneUse() || isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I) || isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<InsertElementInst>(I) || isa<InsertValueInst>(I)) @@ -286,11 +283,11 @@ namespace { void visitBranchInst(BranchInst &I); void visitSwitchInst(SwitchInst &I); void visitInvokeInst(InvokeInst &I) { - assert(0 && "Lowerinvoke pass didn't work!"); + llvm_unreachable("Lowerinvoke pass didn't work!"); } void visitUnwindInst(UnwindInst &I) { - assert(0 && "Lowerinvoke pass didn't work!"); + llvm_unreachable("Lowerinvoke pass didn't work!"); } void visitUnreachableInst(UnreachableInst &I); @@ -321,8 +318,10 @@ namespace { void visitExtractValueInst(ExtractValueInst &I); void visitInstruction(Instruction &I) { - cerr << "C Writer does not know about " << I; - abort(); +#ifndef NDEBUG + errs() << "C Writer does not know about " << I; +#endif + llvm_unreachable(0); } void outputLValue(Instruction *I) { @@ -430,7 +429,7 @@ bool CBackendNameAllUsedStructsAndMergeFunctions::runOnModule(Module &M) { /// printStructReturnPointerFunctionType - This is like printType for a struct /// return type, except, instead of printing the type as void (*)(Struct*, ...) /// print it as "Struct (*)(...)", for struct return functions. -void CWriter::printStructReturnPointerFunctionType(raw_ostream &Out, +void CWriter::printStructReturnPointerFunctionType(formatted_raw_ostream &Out, const AttrListPtr &PAL, const PointerType *TheTy) { const FunctionType *FTy = cast<FunctionType>(TheTy->getElementType()); @@ -466,7 +465,8 @@ void CWriter::printStructReturnPointerFunctionType(raw_ostream &Out, } raw_ostream & -CWriter::printSimpleType(raw_ostream &Out, const Type *Ty, bool isSigned, +CWriter::printSimpleType(formatted_raw_ostream &Out, const Type *Ty, + bool isSigned, const std::string &NameSoFar) { assert((Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) && "Invalid type for printSimpleType"); @@ -505,8 +505,10 @@ CWriter::printSimpleType(raw_ostream &Out, const Type *Ty, bool isSigned, } default: - cerr << "Unknown primitive type: " << *Ty << "\n"; - abort(); +#ifndef NDEBUG + errs() << "Unknown primitive type: " << *Ty << "\n"; +#endif + llvm_unreachable(0); } } @@ -550,17 +552,20 @@ CWriter::printSimpleType(std::ostream &Out, const Type *Ty, bool isSigned, } default: - cerr << "Unknown primitive type: " << *Ty << "\n"; - abort(); +#ifndef NDEBUG + errs() << "Unknown primitive type: " << *Ty << "\n"; +#endif + llvm_unreachable(0); } } // Pass the Type* and the variable name and this prints out the variable // declaration. // -raw_ostream &CWriter::printType(raw_ostream &Out, const Type *Ty, - bool isSigned, const std::string &NameSoFar, - bool IgnoreName, const AttrListPtr &PAL) { +raw_ostream &CWriter::printType(formatted_raw_ostream &Out, + const Type *Ty, + bool isSigned, const std::string &NameSoFar, + bool IgnoreName, const AttrListPtr &PAL) { if (Ty->isPrimitiveType() || Ty->isInteger() || isa<VectorType>(Ty)) { printSimpleType(Out, Ty, isSigned, NameSoFar); return Out; @@ -652,8 +657,7 @@ raw_ostream &CWriter::printType(raw_ostream &Out, const Type *Ty, return Out << TyName << ' ' << NameSoFar; } default: - assert(0 && "Unhandled case in getTypeProps!"); - abort(); + llvm_unreachable("Unhandled case in getTypeProps!"); } return Out; @@ -756,8 +760,7 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty, return Out << TyName << ' ' << NameSoFar; } default: - assert(0 && "Unhandled case in getTypeProps!"); - abort(); + llvm_unreachable("Unhandled case in getTypeProps!"); } return Out; @@ -769,7 +772,8 @@ void CWriter::printConstantArray(ConstantArray *CPA, bool Static) { // ubytes or an array of sbytes with positive values. // const Type *ETy = CPA->getType()->getElementType(); - bool isString = (ETy == Type::Int8Ty || ETy == Type::Int8Ty); + bool isString = (ETy == Type::getInt8Ty(CPA->getContext()) || + ETy == Type::getInt8Ty(CPA->getContext())); // Make sure the last character is a null char, as automatically added by C if (isString && (CPA->getNumOperands() == 0 || @@ -855,10 +859,11 @@ void CWriter::printConstantVector(ConstantVector *CP, bool Static) { static bool isFPCSafeToPrint(const ConstantFP *CFP) { bool ignored; // Do long doubles in hex for now. - if (CFP->getType() != Type::FloatTy && CFP->getType() != Type::DoubleTy) + if (CFP->getType() != Type::getFloatTy(CFP->getContext()) && + CFP->getType() != Type::getDoubleTy(CFP->getContext())) return false; APFloat APF = APFloat(CFP->getValueAPF()); // copy - if (CFP->getType() == Type::FloatTy) + if (CFP->getType() == Type::getFloatTy(CFP->getContext())) APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored); #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A char Buffer[100]; @@ -916,7 +921,7 @@ void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) { Out << ')'; break; default: - assert(0 && "Invalid cast opcode"); + llvm_unreachable("Invalid cast opcode"); } // Print the source type cast @@ -946,7 +951,7 @@ void CWriter::printCast(unsigned opc, const Type *SrcTy, const Type *DstTy) { case Instruction::FPToUI: break; // These don't need a source cast. default: - assert(0 && "Invalid cast opcode"); + llvm_unreachable("Invalid cast opcode"); break; } } @@ -970,12 +975,12 @@ void CWriter::printConstant(Constant *CPV, bool Static) { Out << "("; printCast(CE->getOpcode(), CE->getOperand(0)->getType(), CE->getType()); if (CE->getOpcode() == Instruction::SExt && - CE->getOperand(0)->getType() == Type::Int1Ty) { + CE->getOperand(0)->getType() == Type::getInt1Ty(CPV->getContext())) { // Make sure we really sext from bool here by subtracting from 0 Out << "0-"; } printConstant(CE->getOperand(0), Static); - if (CE->getType() == Type::Int1Ty && + if (CE->getType() == Type::getInt1Ty(CPV->getContext()) && (CE->getOpcode() == Instruction::Trunc || CE->getOpcode() == Instruction::FPToUI || CE->getOpcode() == Instruction::FPToSI || @@ -1055,10 +1060,10 @@ void CWriter::printConstant(Constant *CPV, bool Static) { case ICmpInst::ICMP_UGT: Out << " > "; break; case ICmpInst::ICMP_SGE: case ICmpInst::ICMP_UGE: Out << " >= "; break; - default: assert(0 && "Illegal ICmp predicate"); + default: llvm_unreachable("Illegal ICmp predicate"); } break; - default: assert(0 && "Illegal opcode here!"); + default: llvm_unreachable("Illegal opcode here!"); } printConstantWithCast(CE->getOperand(1), CE->getOpcode()); if (NeedsClosingParens) @@ -1076,7 +1081,7 @@ void CWriter::printConstant(Constant *CPV, bool Static) { else { const char* op = 0; switch (CE->getPredicate()) { - default: assert(0 && "Illegal FCmp predicate"); + default: llvm_unreachable("Illegal FCmp predicate"); case FCmpInst::FCMP_ORD: op = "ord"; break; case FCmpInst::FCMP_UNO: op = "uno"; break; case FCmpInst::FCMP_UEQ: op = "ueq"; break; @@ -1104,9 +1109,11 @@ void CWriter::printConstant(Constant *CPV, bool Static) { return; } default: - cerr << "CWriter Error: Unhandled constant expression: " +#ifndef NDEBUG + errs() << "CWriter Error: Unhandled constant expression: " << *CE << "\n"; - abort(); +#endif + llvm_unreachable(0); } } else if (isa<UndefValue>(CPV) && CPV->getType()->isSingleValueType()) { Out << "(("; @@ -1122,9 +1129,9 @@ void CWriter::printConstant(Constant *CPV, bool Static) { if (ConstantInt *CI = dyn_cast<ConstantInt>(CPV)) { const Type* Ty = CI->getType(); - if (Ty == Type::Int1Ty) + if (Ty == Type::getInt1Ty(CPV->getContext())) Out << (CI->getZExtValue() ? '1' : '0'); - else if (Ty == Type::Int32Ty) + else if (Ty == Type::getInt32Ty(CPV->getContext())) Out << CI->getZExtValue() << 'u'; else if (Ty->getPrimitiveSizeInBits() > 32) Out << CI->getZExtValue() << "ull"; @@ -1151,15 +1158,17 @@ void CWriter::printConstant(Constant *CPV, bool Static) { if (I != FPConstantMap.end()) { // Because of FP precision problems we must load from a stack allocated // value that holds the value in hex. - Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : - FPC->getType() == Type::DoubleTy ? "double" : + Out << "(*(" << (FPC->getType() == Type::getFloatTy(CPV->getContext()) ? + "float" : + FPC->getType() == Type::getDoubleTy(CPV->getContext()) ? + "double" : "long double") << "*)&FPConstant" << I->second << ')'; } else { double V; - if (FPC->getType() == Type::FloatTy) + if (FPC->getType() == Type::getFloatTy(CPV->getContext())) V = FPC->getValueAPF().convertToFloat(); - else if (FPC->getType() == Type::DoubleTy) + else if (FPC->getType() == Type::getDoubleTy(CPV->getContext())) V = FPC->getValueAPF().convertToDouble(); else { // Long double. Convert the number to double, discarding precision. @@ -1189,7 +1198,7 @@ void CWriter::printConstant(Constant *CPV, bool Static) { std::string Num(&Buffer[0], &Buffer[6]); unsigned long Val = strtoul(Num.c_str(), 0, 16); - if (FPC->getType() == Type::FloatTy) + if (FPC->getType() == Type::getFloatTy(FPC->getContext())) Out << "LLVM_NAN" << (Val == QuietNaN ? "" : "S") << "F(\"" << Buffer << "\") /*nan*/ "; else @@ -1198,7 +1207,8 @@ void CWriter::printConstant(Constant *CPV, bool Static) { } else if (IsInf(V)) { // The value is Inf if (V < 0) Out << '-'; - Out << "LLVM_INF" << (FPC->getType() == Type::FloatTy ? "F" : "") + Out << "LLVM_INF" << + (FPC->getType() == Type::getFloatTy(FPC->getContext()) ? "F" : "") << " /*inf*/ "; } else { std::string Num; @@ -1312,8 +1322,10 @@ void CWriter::printConstant(Constant *CPV, bool Static) { } // FALL THROUGH default: - cerr << "Unknown constant type: " << *CPV << "\n"; - abort(); +#ifndef NDEBUG + errs() << "Unknown constant type: " << *CPV << "\n"; +#endif + llvm_unreachable(0); } } @@ -1359,7 +1371,7 @@ bool CWriter::printConstExprCast(const ConstantExpr* CE, bool Static) { } if (NeedsExplicitCast) { Out << "(("; - if (Ty->isInteger() && Ty != Type::Int1Ty) + if (Ty->isInteger() && Ty != Type::getInt1Ty(Ty->getContext())) printSimpleType(Out, Ty, TypeIsSigned); else printType(Out, Ty); // not integer, sign doesn't matter @@ -1419,33 +1431,36 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) { } std::string CWriter::GetValueName(const Value *Operand) { - std::string Name; - - if (!isa<GlobalValue>(Operand) && Operand->getName() != "") { - std::string VarName; - - Name = Operand->getName(); - VarName.reserve(Name.capacity()); - - for (std::string::iterator I = Name.begin(), E = Name.end(); - I != E; ++I) { - char ch = *I; + // Mangle globals with the standard mangler interface for LLC compatibility. + if (const GlobalValue *GV = dyn_cast<GlobalValue>(Operand)) + return Mang->getMangledName(GV); + + std::string Name = Operand->getName(); + + if (Name.empty()) { // Assign unique names to local temporaries. + unsigned &No = AnonValueNumbers[Operand]; + if (No == 0) + No = ++NextAnonValueNumber; + Name = "tmp__" + utostr(No); + } + + std::string VarName; + VarName.reserve(Name.capacity()); - if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || ch == '_')) { - char buffer[5]; - sprintf(buffer, "_%x_", ch); - VarName += buffer; - } else - VarName += ch; - } + for (std::string::iterator I = Name.begin(), E = Name.end(); + I != E; ++I) { + char ch = *I; - Name = "llvm_cbe_" + VarName; - } else { - Name = Mang->getValueName(Operand); + if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || ch == '_')) { + char buffer[5]; + sprintf(buffer, "_%x_", ch); + VarName += buffer; + } else + VarName += ch; } - return Name; + return "llvm_cbe_" + VarName; } /// writeInstComputationInline - Emit the computation for the specified @@ -1454,19 +1469,22 @@ void CWriter::writeInstComputationInline(Instruction &I) { // We can't currently support integer types other than 1, 8, 16, 32, 64. // Validate this. const Type *Ty = I.getType(); - if (Ty->isInteger() && (Ty!=Type::Int1Ty && Ty!=Type::Int8Ty && - Ty!=Type::Int16Ty && Ty!=Type::Int32Ty && Ty!=Type::Int64Ty)) { - cerr << "The C backend does not currently support integer " - << "types of widths other than 1, 8, 16, 32, 64.\n"; - cerr << "This is being tracked as PR 4158.\n"; - abort(); + if (Ty->isInteger() && (Ty!=Type::getInt1Ty(I.getContext()) && + Ty!=Type::getInt8Ty(I.getContext()) && + Ty!=Type::getInt16Ty(I.getContext()) && + Ty!=Type::getInt32Ty(I.getContext()) && + Ty!=Type::getInt64Ty(I.getContext()))) { + llvm_report_error("The C backend does not currently support integer " + "types of widths other than 1, 8, 16, 32, 64.\n" + "This is being tracked as PR 4158."); } // If this is a non-trivial bool computation, make sure to truncate down to // a 1 bit value. This is important because we want "add i1 x, y" to return // "0" when x and y are true, not "2" for example. bool NeedBoolTrunc = false; - if (I.getType() == Type::Int1Ty && !isa<ICmpInst>(I) && !isa<FCmpInst>(I)) + if (I.getType() == Type::getInt1Ty(I.getContext()) && + !isa<ICmpInst>(I) && !isa<FCmpInst>(I)) NeedBoolTrunc = true; if (NeedBoolTrunc) @@ -1615,7 +1633,7 @@ void CWriter::writeOperandWithCast(Value* Operand, const ICmpInst &Cmp) { // If the operand was a pointer, convert to a large integer type. const Type* OpTy = Operand->getType(); if (isa<PointerType>(OpTy)) - OpTy = TD->getIntPtrType(); + OpTy = TD->getIntPtrType(Operand->getContext()); Out << "(("; printSimpleType(Out, OpTy, castIsSigned); @@ -1627,13 +1645,13 @@ void CWriter::writeOperandWithCast(Value* Operand, const ICmpInst &Cmp) { // generateCompilerSpecificCode - This is where we add conditional compilation // directives to cater to specific compilers as need be. // -static void generateCompilerSpecificCode(raw_ostream& Out, +static void generateCompilerSpecificCode(formatted_raw_ostream& Out, const TargetData *TD) { // Alloca is hard to get, and we don't want to include stdlib.h here. Out << "/* get a declaration for alloca */\n" << "#if defined(__CYGWIN__) || defined(__MINGW32__)\n" << "#define alloca(x) __builtin_alloca((x))\n" - << "#define _alloca(x) __builtin_alloca((x))\n" + << "#define _alloca(x) __builtin_alloca((x))\n" << "#elif defined(__APPLE__)\n" << "extern void *__builtin_alloca(unsigned long);\n" << "#define alloca(x) __builtin_alloca(x)\n" @@ -1646,7 +1664,7 @@ static void generateCompilerSpecificCode(raw_ostream& Out, << "extern void *__builtin_alloca(unsigned int);\n" << "#endif\n" << "#define alloca(x) __builtin_alloca(x)\n" - << "#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)\n" + << "#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__arm__)\n" << "#define alloca(x) __builtin_alloca(x)\n" << "#elif defined(_MSC_VER)\n" << "#define inline _inline\n" @@ -1803,8 +1821,34 @@ static SpecialGlobalClass getGlobalVariableClass(const GlobalVariable *GV) { return NotSpecial; } +// PrintEscapedString - Print each character of the specified string, escaping +// it if it is not printable or if it is an escape char. +static void PrintEscapedString(const char *Str, unsigned Length, + raw_ostream &Out) { + for (unsigned i = 0; i != Length; ++i) { + unsigned char C = Str[i]; + if (isprint(C) && C != '\\' && C != '"') + Out << C; + else if (C == '\\') + Out << "\\\\"; + else if (C == '\"') + Out << "\\\""; + else if (C == '\t') + Out << "\\t"; + else + Out << "\\x" << hexdigit(C >> 4) << hexdigit(C & 0x0F); + } +} + +// PrintEscapedString - Print each character of the specified string, escaping +// it if it is not printable or if it is an escape char. +static void PrintEscapedString(const std::string &Str, raw_ostream &Out) { + PrintEscapedString(Str.c_str(), Str.size(), Out); +} bool CWriter::doInitialization(Module &M) { + FunctionPass::doInitialization(M); + // Initialize TheModule = &M; @@ -1855,6 +1899,29 @@ bool CWriter::doInitialization(Module &M) { // First output all the declarations for the program, because C requires // Functions & globals to be declared before they are used. // + if (!M.getModuleInlineAsm().empty()) { + Out << "/* Module asm statements */\n" + << "asm("; + + // Split the string into lines, to make it easier to read the .ll file. + std::string Asm = M.getModuleInlineAsm(); + size_t CurPos = 0; + size_t NewLine = Asm.find_first_of('\n', CurPos); + while (NewLine != std::string::npos) { + // We found a newline, print the portion of the asm string from the + // last newline up to this newline. + Out << "\""; + PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.begin()+NewLine), + Out); + Out << "\\n\"\n"; + CurPos = NewLine+1; + NewLine = Asm.find_first_of('\n', CurPos); + } + Out << "\""; + PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out); + Out << "\");\n" + << "/* End Module asm statements */\n"; + } // Loop over the symbol table, emitting all named constants... printModuleTypes(M.getTypeSymbolTable()); @@ -1910,7 +1977,7 @@ bool CWriter::doInitialization(Module &M) { Out << " __HIDDEN__"; if (I->hasName() && I->getName()[0] == 1) - Out << " LLVM_ASM(\"" << I->getName().c_str()+1 << "\")"; + Out << " LLVM_ASM(\"" << I->getName().substr(1) << "\")"; Out << ";\n"; } @@ -2085,20 +2152,20 @@ void CWriter::printFloatingPointConstants(const Constant *C) { FPConstantMap[FPC] = FPCounter; // Number the FP constants - if (FPC->getType() == Type::DoubleTy) { + if (FPC->getType() == Type::getDoubleTy(FPC->getContext())) { double Val = FPC->getValueAPF().convertToDouble(); uint64_t i = FPC->getValueAPF().bitcastToAPInt().getZExtValue(); Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ << " = 0x" << utohexstr(i) << "ULL; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::FloatTy) { + } else if (FPC->getType() == Type::getFloatTy(FPC->getContext())) { float Val = FPC->getValueAPF().convertToFloat(); uint32_t i = (uint32_t)FPC->getValueAPF().bitcastToAPInt(). getZExtValue(); Out << "static const ConstantFloatTy FPConstant" << FPCounter++ << " = 0x" << utohexstr(i) << "U; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::X86_FP80Ty) { + } else if (FPC->getType() == Type::getX86_FP80Ty(FPC->getContext())) { // api needed to prevent premature destruction APInt api = FPC->getValueAPF().bitcastToAPInt(); const uint64_t *p = api.getRawData(); @@ -2106,7 +2173,8 @@ void CWriter::printFloatingPointConstants(const Constant *C) { << " = { 0x" << utohexstr(p[0]) << "ULL, 0x" << utohexstr((uint16_t)p[1]) << ",{0,0,0}" << "}; /* Long double constant */\n"; - } else if (FPC->getType() == Type::PPC_FP128Ty) { + } else if (FPC->getType() == Type::getPPC_FP128Ty(FPC->getContext()) || + FPC->getType() == Type::getFP128Ty(FPC->getContext())) { APInt api = FPC->getValueAPF().bitcastToAPInt(); const uint64_t *p = api.getRawData(); Out << "static const ConstantFP128Ty FPConstant" << FPCounter++ @@ -2115,7 +2183,7 @@ void CWriter::printFloatingPointConstants(const Constant *C) { << "}; /* Long double constant */\n"; } else { - assert(0 && "Unknown float type!"); + llvm_unreachable("Unknown float type!"); } } @@ -2215,6 +2283,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { case CallingConv::X86_FastCall: Out << "__attribute__((fastcall)) "; break; + default: + break; } // Loop over the arguments, printing them... @@ -2351,7 +2421,8 @@ void CWriter::printFunction(Function &F) { printType(Out, AI->getAllocatedType(), false, GetValueName(AI)); Out << "; /* Address-exposed local */\n"; PrintedVar = true; - } else if (I->getType() != Type::VoidTy && !isInlinableInst(*I)) { + } else if (I->getType() != Type::getVoidTy(F.getContext()) && + !isInlinableInst(*I)) { Out << " "; printType(Out, I->getType(), false, GetValueName(&*I)); Out << ";\n"; @@ -2428,7 +2499,8 @@ void CWriter::printBasicBlock(BasicBlock *BB) { for (BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; ++II) { if (!isInlinableInst(*II) && !isDirectAlloca(II)) { - if (II->getType() != Type::VoidTy && !isInlineAsm(*II)) + if (II->getType() != Type::getVoidTy(BB->getContext()) && + !isInlineAsm(*II)) outputLValue(II); else Out << " "; @@ -2603,8 +2675,9 @@ void CWriter::visitBinaryOperator(Instruction &I) { // We must cast the results of binary operations which might be promoted. bool needsCast = false; - if ((I.getType() == Type::Int8Ty) || (I.getType() == Type::Int16Ty) - || (I.getType() == Type::FloatTy)) { + if ((I.getType() == Type::getInt8Ty(I.getContext())) || + (I.getType() == Type::getInt16Ty(I.getContext())) + || (I.getType() == Type::getFloatTy(I.getContext()))) { needsCast = true; Out << "(("; printType(Out, I.getType(), false); @@ -2623,9 +2696,9 @@ void CWriter::visitBinaryOperator(Instruction &I) { Out << ")"; } else if (I.getOpcode() == Instruction::FRem) { // Output a call to fmod/fmodf instead of emitting a%b - if (I.getType() == Type::FloatTy) + if (I.getType() == Type::getFloatTy(I.getContext())) Out << "fmodf("; - else if (I.getType() == Type::DoubleTy) + else if (I.getType() == Type::getDoubleTy(I.getContext())) Out << "fmod("; else // all 3 flavors of long double Out << "fmodl("; @@ -2663,7 +2736,11 @@ void CWriter::visitBinaryOperator(Instruction &I) { case Instruction::Shl : Out << " << "; break; case Instruction::LShr: case Instruction::AShr: Out << " >> "; break; - default: cerr << "Invalid operator type!" << I; abort(); + default: +#ifndef NDEBUG + errs() << "Invalid operator type!" << I; +#endif + llvm_unreachable(0); } writeOperandWithCast(I.getOperand(1), I.getOpcode()); @@ -2700,7 +2777,11 @@ void CWriter::visitICmpInst(ICmpInst &I) { case ICmpInst::ICMP_SLT: Out << " < "; break; case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_SGT: Out << " > "; break; - default: cerr << "Invalid icmp predicate!" << I; abort(); + default: +#ifndef NDEBUG + errs() << "Invalid icmp predicate!" << I; +#endif + llvm_unreachable(0); } writeOperandWithCast(I.getOperand(1), I); @@ -2724,7 +2805,7 @@ void CWriter::visitFCmpInst(FCmpInst &I) { const char* op = 0; switch (I.getPredicate()) { - default: assert(0 && "Illegal FCmp predicate"); + default: llvm_unreachable("Illegal FCmp predicate"); case FCmpInst::FCMP_ORD: op = "ord"; break; case FCmpInst::FCMP_UNO: op = "uno"; break; case FCmpInst::FCMP_UEQ: op = "ueq"; break; @@ -2752,7 +2833,7 @@ void CWriter::visitFCmpInst(FCmpInst &I) { static const char * getFloatBitCastField(const Type *Ty) { switch (Ty->getTypeID()) { - default: assert(0 && "Invalid Type"); + default: llvm_unreachable("Invalid Type"); case Type::FloatTyID: return "Float"; case Type::DoubleTyID: return "Double"; case Type::IntegerTyID: { @@ -2784,12 +2865,13 @@ void CWriter::visitCastInst(CastInst &I) { printCast(I.getOpcode(), SrcTy, DstTy); // Make a sext from i1 work by subtracting the i1 from 0 (an int). - if (SrcTy == Type::Int1Ty && I.getOpcode() == Instruction::SExt) + if (SrcTy == Type::getInt1Ty(I.getContext()) && + I.getOpcode() == Instruction::SExt) Out << "0-"; writeOperand(I.getOperand(0)); - if (DstTy == Type::Int1Ty && + if (DstTy == Type::getInt1Ty(I.getContext()) && (I.getOpcode() == Instruction::Trunc || I.getOpcode() == Instruction::FPToUI || I.getOpcode() == Instruction::FPToSI || @@ -3020,10 +3102,12 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID, Out << ", "; // Output the last argument to the enclosing function. if (I.getParent()->getParent()->arg_empty()) { - cerr << "The C backend does not currently support zero " + std::string msg; + raw_string_ostream Msg(msg); + Msg << "The C backend does not currently support zero " << "argument varargs functions, such as '" - << I.getParent()->getParent()->getName() << "'!\n"; - abort(); + << I.getParent()->getParent()->getName() << "'!"; + llvm_report_error(Msg.str()); } writeOperand(--I.getParent()->getParent()->arg_end()); Out << ')'; @@ -3092,16 +3176,15 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID, case Intrinsic::dbg_stoppoint: { // If we use writeOperand directly we get a "u" suffix which is rejected // by gcc. - std::stringstream SPIStr; DbgStopPointInst &SPI = cast<DbgStopPointInst>(I); - SPI.getDirectory()->print(SPIStr); + std::string dir; + GetConstantStringInfo(SPI.getDirectory(), dir); + std::string file; + GetConstantStringInfo(SPI.getFileName(), file); Out << "\n#line " << SPI.getLine() - << " \""; - Out << SPIStr.str(); - SPIStr.clear(); - SPI.getFileName()->print(SPIStr); - Out << SPIStr.str() << "\"\n"; + << " \"" + << dir << '/' << file << "\"\n"; return true; } case Intrinsic::x86_sse_cmp_ss: @@ -3113,7 +3196,7 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID, Out << ')'; // Multiple GCC builtins multiplex onto this intrinsic. switch (cast<ConstantInt>(I.getOperand(3))->getZExtValue()) { - default: assert(0 && "Invalid llvm.x86.sse.cmp!"); + default: llvm_unreachable("Invalid llvm.x86.sse.cmp!"); case 0: Out << "__builtin_ia32_cmpeq"; break; case 1: Out << "__builtin_ia32_cmplt"; break; case 2: Out << "__builtin_ia32_cmple"; break; @@ -3159,27 +3242,25 @@ std::string CWriter::InterpretASMConstraint(InlineAsm::ConstraintInfo& c) { const char *const *table = 0; - //Grab the translation table from TargetAsmInfo if it exists + // Grab the translation table from MCAsmInfo if it exists. if (!TAsm) { + std::string Triple = TheModule->getTargetTriple(); + if (Triple.empty()) + Triple = llvm::sys::getHostTriple(); + std::string E; - const TargetMachineRegistry::entry* Match = - TargetMachineRegistry::getClosestStaticTargetForModule(*TheModule, E); - if (Match) { - //Per platform Target Machines don't exist, so create it - // this must be done only once - const TargetMachine* TM = Match->CtorFn(*TheModule, ""); - TAsm = TM->getTargetAsmInfo(); - } + if (const Target *Match = TargetRegistry::lookupTarget(Triple, E)) + TAsm = Match->createAsmInfo(Triple); } if (TAsm) table = TAsm->getAsmCBE(); - //Search the translation table if it exists + // Search the translation table if it exists. for (int i = 0; table && table[i]; i += 2) if (c.Codes[0] == table[i]) return table[i+1]; - //default is identity + // Default is identity. return c.Codes[0]; } @@ -3215,7 +3296,7 @@ void CWriter::visitInlineAsm(CallInst &CI) { std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints(); std::vector<std::pair<Value*, int> > ResultVals; - if (CI.getType() == Type::VoidTy) + if (CI.getType() == Type::getVoidTy(CI.getContext())) ; else if (const StructType *ST = dyn_cast<StructType>(CI.getType())) { for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) @@ -3325,7 +3406,7 @@ void CWriter::visitInlineAsm(CallInst &CI) { } void CWriter::visitMallocInst(MallocInst &I) { - assert(0 && "lowerallocations pass didn't work!"); + llvm_unreachable("lowerallocations pass didn't work!"); } void CWriter::visitAllocaInst(AllocaInst &I) { @@ -3342,7 +3423,7 @@ void CWriter::visitAllocaInst(AllocaInst &I) { } void CWriter::visitFreeInst(FreeInst &I) { - assert(0 && "lowerallocations pass didn't work!"); + llvm_unreachable("lowerallocations pass didn't work!"); } void CWriter::printGEPExpression(Value *Ptr, gep_type_iterator I, @@ -3603,7 +3684,7 @@ void CWriter::visitExtractValueInst(ExtractValueInst &EVI) { //===----------------------------------------------------------------------===// bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM, - raw_ostream &o, + formatted_raw_ostream &o, CodeGenFileType FileType, CodeGenOpt::Level OptLevel) { if (FileType != TargetMachine::AssemblyFile) return true; diff --git a/lib/Target/CBackend/CTargetMachine.h b/lib/Target/CBackend/CTargetMachine.h index 8b26245..715bbda 100644 --- a/lib/Target/CBackend/CTargetMachine.h +++ b/lib/Target/CBackend/CTargetMachine.h @@ -20,23 +20,20 @@ namespace llvm { struct CTargetMachine : public TargetMachine { - const TargetData DataLayout; // Calculates type size & alignment - - CTargetMachine(const Module &M, const std::string &FS) - : DataLayout(&M) {} + CTargetMachine(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 must be requested explicitly on - // llc command line. - static unsigned getModuleMatchQuality(const Module &M) { return 0; } - virtual const TargetData *getTargetData() const { return &DataLayout; } + virtual const TargetData *getTargetData() const { return 0; } }; +extern Target TheCBackendTarget; + } // End llvm namespace diff --git a/lib/Target/CBackend/Makefile b/lib/Target/CBackend/Makefile index 336de0c..3b5ef0f 100644 --- a/lib/Target/CBackend/Makefile +++ b/lib/Target/CBackend/Makefile @@ -9,6 +9,9 @@ LEVEL = ../../.. LIBRARYNAME = LLVMCBackend + +DIRS = TargetInfo + include $(LEVEL)/Makefile.common CompileCommonOpts += -Wno-format diff --git a/lib/Target/CBackend/TargetInfo/CBackendTargetInfo.cpp b/lib/Target/CBackend/TargetInfo/CBackendTargetInfo.cpp new file mode 100644 index 0000000..f7e8ff2 --- /dev/null +++ b/lib/Target/CBackend/TargetInfo/CBackendTargetInfo.cpp @@ -0,0 +1,19 @@ +//===-- CBackendTargetInfo.cpp - CBackend Target Implementation -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CTargetMachine.h" +#include "llvm/Module.h" +#include "llvm/Target/TargetRegistry.h" +using namespace llvm; + +Target llvm::TheCBackendTarget; + +extern "C" void LLVMInitializeCBackendTargetInfo() { + RegisterTarget<> X(TheCBackendTarget, "c", "C backend"); +} diff --git a/lib/Target/CBackend/TargetInfo/CMakeLists.txt b/lib/Target/CBackend/TargetInfo/CMakeLists.txt new file mode 100644 index 0000000..5b35fa7 --- /dev/null +++ b/lib/Target/CBackend/TargetInfo/CMakeLists.txt @@ -0,0 +1,6 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMCBackendInfo + CBackendTargetInfo.cpp + ) + diff --git a/lib/Target/CBackend/TargetInfo/Makefile b/lib/Target/CBackend/TargetInfo/Makefile new file mode 100644 index 0000000..d4d5e15 --- /dev/null +++ b/lib/Target/CBackend/TargetInfo/Makefile @@ -0,0 +1,15 @@ +##===- lib/Target/CBackend/TargetInfo/Makefile -------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMCBackendInfo + +# Hack: we need to include 'main' target directory to grab private headers +CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common |