X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FVMCore%2FAsmWriter.cpp;h=55d037db141db02ae4fe7d1d3d0807bd9255afcb;hb=e6be34a53ecbe8c2ff9f0793b13d847e94c0de91;hp=656a7bed74e2d46013cd1ce7273b93e162ea5fe4;hpb=a80e1181b78183dc36ec6568559d38faa86981f0;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 656a7bed74e..55d037db141 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -20,7 +20,7 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/ParameterAttributes.h" +#include "llvm/ParamAttrsList.h" #include "llvm/InlineAsm.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" @@ -33,6 +33,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Streams.h" #include +#include using namespace llvm; namespace llvm { @@ -56,10 +57,10 @@ public: /// @{ public: /// @brief Construct from a module - SlotMachine(const Module *M); + explicit SlotMachine(const Module *M); /// @brief Construct from a function, starting out in incorp state. - SlotMachine(const Function *F); + explicit SlotMachine(const Function *F); /// @} /// @name Accessors @@ -135,8 +136,10 @@ public: } // end namespace llvm +char PrintModulePass::ID = 0; static RegisterPass X("printm", "Print module to stderr"); +char PrintFunctionPass::ID = 0; static RegisterPass Y("print","Print function to stderr"); @@ -176,17 +179,42 @@ static SlotMachine *createSlotMachine(const Value *V) { /// NameNeedsQuotes - Return true if the specified llvm name should be wrapped /// with ""'s. -static bool NameNeedsQuotes(const std::string &Name) { - if (Name[0] >= '0' && Name[0] <= '9') return true; - // Scan to see if we have any characters that are not on the "white list" +static std::string QuoteNameIfNeeded(const std::string &Name) { + std::string result; + bool needsQuotes = Name[0] >= '0' && Name[0] <= '9'; + // Scan the name to see if it needs quotes and to replace funky chars with + // their octal equivalent. for (unsigned i = 0, e = Name.size(); i != e; ++i) { char C = Name[i]; assert(C != '"' && "Illegal character in LLVM value name!"); - if ((C < 'a' || C > 'z') && (C < 'A' || C > 'Z') && (C < '0' || C > '9') && - C != '-' && C != '.' && C != '_') - return true; + if (isalnum(C) || C == '-' || C == '.' || C == '_') + result += C; + else if (C == '\\') { + needsQuotes = true; + result += "\\\\"; + } else if (isprint(C)) { + needsQuotes = true; + result += C; + } else { + needsQuotes = true; + result += "\\"; + char hex1 = (C >> 4) & 0x0F; + if (hex1 < 10) + result += hex1 + '0'; + else + result += hex1 - 10 + 'A'; + char hex2 = C & 0x0F; + if (hex2 < 10) + result += hex2 + '0'; + else + result += hex2 - 10 + 'A'; + } } - return false; + if (needsQuotes) { + result.insert(0,"\""); + result += '"'; + } + return result; } enum PrefixType { @@ -200,20 +228,11 @@ enum PrefixType { /// surrounded with ""'s (if it has special chars in it). static std::string getLLVMName(const std::string &Name, PrefixType Prefix) { assert(!Name.empty() && "Cannot get empty name!"); - - // First character cannot start with a number... - if (NameNeedsQuotes(Name)) { - if (Prefix == GlobalPrefix) - return "@\"" + Name + "\""; - return "\"" + Name + "\""; - } - - // If we get here, then the identifier is legal to use as a "VarID". switch (Prefix) { default: assert(0 && "Bad prefix!"); - case GlobalPrefix: return '@' + Name; - case LabelPrefix: return Name; - case LocalPrefix: return '%' + Name; + case GlobalPrefix: return '@' + QuoteNameIfNeeded(Name); + case LabelPrefix: return QuoteNameIfNeeded(Name); + case LocalPrefix: return '%' + QuoteNameIfNeeded(Name); } } @@ -286,28 +305,17 @@ static void calcTypeName(const Type *Ty, const FunctionType *FTy = cast(Ty); calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result); Result += " ("; - unsigned Idx = 1; - const ParamAttrsList *Attrs = FTy->getParamAttrs(); for (FunctionType::param_iterator I = FTy->param_begin(), - E = FTy->param_end(); I != E; ++I) { + E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) Result += ", "; calcTypeName(*I, TypeStack, TypeNames, Result); - if (Attrs && Attrs->getParamAttrs(Idx) != ParamAttr::None) { - Result += + " "; - Result += Attrs->getParamAttrsTextByIndex(Idx); - } - Idx++; } if (FTy->isVarArg()) { if (FTy->getNumParams()) Result += ", "; Result += "..."; } Result += ")"; - if (Attrs && Attrs->getParamAttrs(0) != ParamAttr::None) { - Result += " "; - Result += Attrs->getParamAttrsTextByIndex(0); - } break; } case Type::StructTyID: { @@ -326,11 +334,15 @@ static void calcTypeName(const Type *Ty, Result += '>'; break; } - case Type::PointerTyID: - calcTypeName(cast(Ty)->getElementType(), + case Type::PointerTyID: { + const PointerType *PTy = cast(Ty); + calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result); + if (unsigned AddressSpace = PTy->getAddressSpace()) + Result += " addrspace(" + utostr(AddressSpace) + ")"; Result += "*"; break; + } case Type::ArrayTyID: { const ArrayType *ATy = cast(Ty); Result += "[" + utostr(ATy->getNumElements()) + " x "; @@ -462,32 +474,68 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, else Out << CI->getValue().toStringSigned(10); } else if (const ConstantFP *CFP = dyn_cast(CV)) { - // We would like to output the FP constant value in exponential notation, - // but we cannot do this if doing so will lose precision. Check here to - // make sure that we only output it in exponential format if we can parse - // the value back and get the same value. - // - std::string StrVal = ftostr(CFP->getValue()); - - // Check to make sure that the stringized number is not some string like - // "Inf" or NaN, that atof will accept, but the lexer will not. Check that - // the string matches the "[-+]?[0-9]" regex. - // - if ((StrVal[0] >= '0' && StrVal[0] <= '9') || - ((StrVal[0] == '-' || StrVal[0] == '+') && - (StrVal[1] >= '0' && StrVal[1] <= '9'))) - // Reparse stringized version! - if (atof(StrVal.c_str()) == CFP->getValue()) { - Out << StrVal; - return; + if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble || + &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) { + // We would like to output the FP constant value in exponential notation, + // but we cannot do this if doing so will lose precision. Check here to + // make sure that we only output it in exponential format if we can parse + // the value back and get the same value. + // + bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble; + double Val = (isDouble) ? CFP->getValueAPF().convertToDouble() : + CFP->getValueAPF().convertToFloat(); + std::string StrVal = ftostr(CFP->getValueAPF()); + + // Check to make sure that the stringized number is not some string like + // "Inf" or NaN, that atof will accept, but the lexer will not. Check + // that the string matches the "[-+]?[0-9]" regex. + // + if ((StrVal[0] >= '0' && StrVal[0] <= '9') || + ((StrVal[0] == '-' || StrVal[0] == '+') && + (StrVal[1] >= '0' && StrVal[1] <= '9'))) { + // Reparse stringized version! + if (atof(StrVal.c_str()) == Val) { + Out << StrVal; + return; + } } - - // Otherwise we could not reparse it to exactly the same value, so we must - // output the string in hexadecimal format! - assert(sizeof(double) == sizeof(uint64_t) && - "assuming that double is 64 bits!"); - Out << "0x" << utohexstr(DoubleToBits(CFP->getValue())); - + // Otherwise we could not reparse it to exactly the same value, so we must + // output the string in hexadecimal format! + assert(sizeof(double) == sizeof(uint64_t) && + "assuming that double is 64 bits!"); + Out << "0x" << utohexstr(DoubleToBits(Val)); + } else { + // Some form of long double. These appear as a magic letter identifying + // the type, then a fixed number of hex digits. + Out << "0x"; + if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended) + Out << 'K'; + else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad) + Out << 'L'; + else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) + Out << 'M'; + else + assert(0 && "Unsupported floating point type"); + // api needed to prevent premature destruction + APInt api = CFP->getValueAPF().convertToAPInt(); + const uint64_t* p = api.getRawData(); + uint64_t word = *p; + int shiftcount=60; + int width = api.getBitWidth(); + for (int j=0; j>shiftcount) & 15; + if (nibble < 10) + Out << (unsigned char)(nibble + '0'); + else + Out << (unsigned char)(nibble - 10 + 'A'); + if (shiftcount == 0) { + word = *(++p); + shiftcount = 64; + if (width-j-4 < 64) + shiftcount = width-j-4; + } + } + } } else if (isa(CV)) { Out << "zeroinitializer"; } else if (const ConstantArray *CA = dyn_cast(CV)) { @@ -694,6 +742,7 @@ public: inline void write(const Type *Ty) { printType(Ty); } void writeOperand(const Value *Op, bool PrintType); + void writeParamOperand(const Value *Operand, ParameterAttributes Attrs); const Module* getModule() { return TheModule; } @@ -703,7 +752,7 @@ private: void printGlobal(const GlobalVariable *GV); void printAlias(const GlobalAlias *GV); void printFunction(const Function *F); - void printArgument(const Argument *FA, uint16_t ParamAttrs); + void printArgument(const Argument *FA, ParameterAttributes Attrs); void printBasicBlock(const BasicBlock *BB); void printInstruction(const Instruction &I); @@ -734,25 +783,17 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { else if (const FunctionType *FTy = dyn_cast(Ty)) { printType(FTy->getReturnType()); Out << " ("; - unsigned Idx = 1; - const ParamAttrsList *Attrs = FTy->getParamAttrs(); for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) Out << ", "; printType(*I); - if (Attrs && Attrs->getParamAttrs(Idx) != ParamAttr::None) { - Out << " " << Attrs->getParamAttrsTextByIndex(Idx); - } - Idx++; } if (FTy->isVarArg()) { if (FTy->getNumParams()) Out << ", "; Out << "..."; } Out << ')'; - if (Attrs && Attrs->getParamAttrs(0) != ParamAttr::None) - Out << ' ' << Attrs->getParamAttrsTextByIndex(0); } else if (const StructType *STy = dyn_cast(Ty)) { if (STy->isPacked()) Out << '<'; @@ -767,7 +808,10 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { if (STy->isPacked()) Out << '>'; } else if (const PointerType *PTy = dyn_cast(Ty)) { - printType(PTy->getElementType()) << '*'; + printType(PTy->getElementType()); + if (unsigned AddressSpace = PTy->getAddressSpace()) + Out << " addrspace(" << AddressSpace << ")"; + Out << '*'; } else if (const ArrayType *ATy = dyn_cast(Ty)) { Out << '[' << ATy->getNumElements() << " x "; printType(ATy->getElementType()) << ']'; @@ -795,6 +839,21 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { } } +void AssemblyWriter::writeParamOperand(const Value *Operand, + ParameterAttributes Attrs) { + if (Operand == 0) { + Out << ""; + } else { + Out << ' '; + // Print the type + printType(Operand->getType()); + // Print parameter attributes list + if (Attrs != ParamAttr::None) + Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs); + // Print the operand + WriteAsOperandInternal(Out, Operand, TypeNames, &Machine); + } +} void AssemblyWriter::printModule(const Module *M) { if (!M->getModuleIdentifier().empty() && @@ -863,12 +922,13 @@ void AssemblyWriter::printModule(const Module *M) { void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->hasName()) Out << getLLVMName(GV->getName(), GlobalPrefix) << " = "; - if (!GV->hasInitializer()) + if (!GV->hasInitializer()) { switch (GV->getLinkage()) { case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; default: Out << "external "; break; - } else { + } + } else { switch (GV->getLinkage()) { case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; @@ -886,6 +946,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { default: assert(0 && "Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; } } @@ -899,6 +960,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { writeOperand(GV->getInitializer(), false); } + if (unsigned AddressSpace = GV->getType()->getAddressSpace()) + Out << " addrspace(" << AddressSpace << ") "; + if (GV->hasSection()) Out << ", section \"" << GV->getSection() << '"'; if (GV->getAlignment()) @@ -914,6 +978,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { default: assert(0 && "Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; } Out << "alias "; @@ -926,8 +991,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { assert(0 && "Invalid alias linkage"); } - const Constant *Aliasee = dyn_cast_or_null(GA->getAliasee()); - assert(Aliasee && "Aliasee cannot be null"); + const Constant *Aliasee = GA->getAliasee(); if (const GlobalVariable *GV = dyn_cast(Aliasee)) { printType(GV->getType()); @@ -975,31 +1039,28 @@ void AssemblyWriter::printFunction(const Function *F) { if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out); if (F->isDeclaration()) - switch (F->getLinkage()) { - case GlobalValue::DLLImportLinkage: Out << "declare dllimport "; break; - case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break; - default: Out << "declare "; - } - else { + Out << "declare "; + else Out << "define "; - switch (F->getLinkage()) { - case GlobalValue::InternalLinkage: Out << "internal "; break; - case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; - case GlobalValue::WeakLinkage: Out << "weak "; break; - case GlobalValue::AppendingLinkage: Out << "appending "; break; - case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; - case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; - case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; - case GlobalValue::ExternalLinkage: break; - case GlobalValue::GhostLinkage: - cerr << "GhostLinkage not allowed in AsmWriter!\n"; - abort(); - } - switch (F->getVisibility()) { - default: assert(0 && "Invalid visibility style!"); - case GlobalValue::DefaultVisibility: break; - case GlobalValue::HiddenVisibility: Out << "hidden "; break; - } + + switch (F->getLinkage()) { + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; + case GlobalValue::WeakLinkage: Out << "weak "; break; + case GlobalValue::AppendingLinkage: Out << "appending "; break; + case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; + case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; + case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; + case GlobalValue::ExternalLinkage: break; + case GlobalValue::GhostLinkage: + cerr << "GhostLinkage not allowed in AsmWriter!\n"; + abort(); + } + switch (F->getVisibility()) { + default: assert(0 && "Invalid visibility style!"); + case GlobalValue::DefaultVisibility: break; + case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; } // Print the calling convention. @@ -1013,7 +1074,7 @@ void AssemblyWriter::printFunction(const Function *F) { } const FunctionType *FT = F->getFunctionType(); - const ParamAttrsList *Attrs = FT->getParamAttrs(); + const ParamAttrsList *Attrs = F->getParamAttrs(); printType(F->getReturnType()) << ' '; if (!F->getName().empty()) Out << getLLVMName(F->getName(), GlobalPrefix); @@ -1032,7 +1093,7 @@ void AssemblyWriter::printFunction(const Function *F) { // Insert commas as we go... the first arg doesn't get a comma if (I != F->arg_begin()) Out << ", "; printArgument(I, (Attrs ? Attrs->getParamAttrs(Idx) - : uint16_t(ParamAttr::None))); + : ParamAttr::None)); Idx++; } } else { @@ -1044,7 +1105,7 @@ void AssemblyWriter::printFunction(const Function *F) { // Output type... printType(FT->getParamType(i)); - unsigned ArgAttrs = ParamAttr::None; + ParameterAttributes ArgAttrs = ParamAttr::None; if (Attrs) ArgAttrs = Attrs->getParamAttrs(i+1); if (ArgAttrs != ParamAttr::None) Out << ' ' << ParamAttrsList::getParamAttrsText(ArgAttrs); @@ -1063,6 +1124,8 @@ void AssemblyWriter::printFunction(const Function *F) { Out << " section \"" << F->getSection() << '"'; if (F->getAlignment()) Out << " align " << F->getAlignment(); + if (F->hasCollector()) + Out << " gc \"" << F->getCollector() << '"'; if (F->isDeclaration()) { Out << "\n"; @@ -1082,10 +1145,12 @@ void AssemblyWriter::printFunction(const Function *F) { /// printArgument - This member is called for every argument that is passed into /// the function. Simply print it out /// -void AssemblyWriter::printArgument(const Argument *Arg, uint16_t Attrs) { +void AssemblyWriter::printArgument(const Argument *Arg, + ParameterAttributes Attrs) { // Output type... printType(Arg->getType()); + // Output parameter attributes list if (Attrs != ParamAttr::None) Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs); @@ -1226,6 +1291,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(I.getOperand(op ), false); Out << ','; writeOperand(I.getOperand(op+1), false); Out << " ]"; } + } else if (const GetResultInst *GRI = dyn_cast(&I)) { + writeOperand(I.getOperand(0), true); + Out << ", " << GRI->getIndex(); } else if (isa(I) && !Operand) { Out << " void"; } else if (const CallInst *CI = dyn_cast(&I)) { @@ -1234,15 +1302,15 @@ void AssemblyWriter::printInstruction(const Instruction &I) { case CallingConv::C: break; // default case CallingConv::Fast: Out << " fastcc"; break; case CallingConv::Cold: Out << " coldcc"; break; - case CallingConv::X86_StdCall: Out << "x86_stdcallcc "; break; - case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break; + case CallingConv::X86_StdCall: Out << " x86_stdcallcc"; break; + case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break; default: Out << " cc" << CI->getCallingConv(); break; } const PointerType *PTy = cast(Operand->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - const ParamAttrsList *PAL = FTy->getParamAttrs(); + const ParamAttrsList *PAL = CI->getParamAttrs(); // If possible, print out the short form of the call instruction. We can // only do this if the first argument is a pointer to a nonvararg function, @@ -1260,9 +1328,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 1) Out << ','; - writeOperand(I.getOperand(op), true); - if (PAL && PAL->getParamAttrs(op) != ParamAttr::None) - Out << " " << PAL->getParamAttrsTextByIndex(op); + writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op) : + ParamAttr::None); } Out << " )"; if (PAL && PAL->getParamAttrs(0) != ParamAttr::None) @@ -1271,7 +1338,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { const PointerType *PTy = cast(Operand->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - const ParamAttrsList *PAL = FTy->getParamAttrs(); + const ParamAttrsList *PAL = II->getParamAttrs(); // Print the calling convention being used. switch (II->getCallingConv()) { @@ -1300,9 +1367,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 3) Out << ','; - writeOperand(I.getOperand(op), true); - if (PAL && PAL->getParamAttrs(op-2) != ParamAttr::None) - Out << " " << PAL->getParamAttrsTextByIndex(op-2); + writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op-2) : + ParamAttr::None); } Out << " )"; @@ -1456,9 +1522,10 @@ ParamAttrsList::dump() const { cerr << "PAL[ "; for (unsigned i = 0; i < attrs.size(); ++i) { uint16_t index = getParamIndex(i); - uint16_t attrs = getParamAttrs(index); + ParameterAttributes attrs = getParamAttrs(index); cerr << "{" << index << "," << attrs << "} "; } + cerr << "]\n"; }