X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FAsmWriter.cpp;h=68cf438e29a55ab9c90ac5789e8ea860845023d0;hb=b5bd026a756d8650f2a94607c9b1dc34cf1c024a;hp=daf3a31a29b57abee21d967afc32604f86c89455;hpb=8dae138d06df9cecbee421ef645d0b74f9ac13d7;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index daf3a31a29b..68cf438e29a 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -39,14 +39,6 @@ using namespace llvm; // Make virtual table appear in this compilation unit. AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {} -char PrintModulePass::ID = 0; -static RegisterPass -X("printm", "Print module to stderr"); -char PrintFunctionPass::ID = 0; -static RegisterPass -Y("print","Print function to stderr"); - - //===----------------------------------------------------------------------===// // Helper Functions //===----------------------------------------------------------------------===// @@ -68,58 +60,30 @@ static const Module *getModuleFromVal(const Value *V) { return 0; } - -/// NameNeedsQuotes - Return true if the specified llvm name should be wrapped -/// with ""'s. -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 (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'; - } - } - if (needsQuotes) { - result.insert(0,"\""); - result += '"'; +// 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 != '"' && isprint(C)) + Out << C; + else + Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); } - return result; } -/// getLLVMName - Turn the specified string into an 'LLVM name', which is -/// surrounded with ""'s and escaped if it has special chars in it. -static std::string getLLVMName(const std::string &Name) { - assert(!Name.empty() && "Cannot get empty name!"); - return QuoteNameIfNeeded(Name); +// 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); } enum PrefixType { GlobalPrefix, LabelPrefix, - LocalPrefix + LocalPrefix, + NoPrefix }; /// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either @@ -130,13 +94,14 @@ static void PrintLLVMName(raw_ostream &OS, const char *NameStr, assert(NameStr && "Cannot get empty name!"); switch (Prefix) { default: assert(0 && "Bad prefix!"); + case NoPrefix: break; case GlobalPrefix: OS << '@'; break; case LabelPrefix: break; case LocalPrefix: OS << '%'; break; } // Scan the name to see if it needs quotes first. - bool NeedsQuotes = NameStr[0] >= '0' && NameStr[0] <= '9'; + bool NeedsQuotes = isdigit(NameStr[0]); if (!NeedsQuotes) { for (unsigned i = 0; i != NameLen; ++i) { char C = NameStr[i]; @@ -156,30 +121,20 @@ static void PrintLLVMName(raw_ostream &OS, const char *NameStr, // Okay, we need quotes. Output the quotes and escape any scary characters as // needed. OS << '"'; - for (unsigned i = 0; i != NameLen; ++i) { - char C = NameStr[i]; - assert(C != '"' && "Illegal character in LLVM value name!"); - if (C == '\\') { - OS << "\\\\"; - } else if (isprint(C)) { - OS << C; - } else { - OS << '\\'; - char hex1 = (C >> 4) & 0x0F; - if (hex1 < 10) - OS << (char)(hex1 + '0'); - else - OS << (char)(hex1 - 10 + 'A'); - char hex2 = C & 0x0F; - if (hex2 < 10) - OS << (char)(hex2 + '0'); - else - OS << (char)(hex2 - 10 + 'A'); - } - } + PrintEscapedString(NameStr, NameLen, OS); OS << '"'; } +/// getLLVMName - Turn the specified string into an 'LLVM name', which is +/// surrounded with ""'s and escaped if it has special chars in it. +static std::string getLLVMName(const std::string &Name) { + assert(!Name.empty() && "Cannot get empty name!"); + std::string result; + raw_string_ostream OS(result); + PrintLLVMName(OS, Name.c_str(), Name.length(), NoPrefix); + return OS.str(); +} + /// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either /// prefixed with % (if the string only contains simple characters) or is /// surrounded with ""'s (if it has special chars in it). Print it out. @@ -385,7 +340,7 @@ int SlotTracker::getGlobalSlot(const GlobalValue *V) { // Find the type plane in the module map ValueMap::iterator MI = mMap.find(V); - return MI == mMap.end() ? -1 : MI->second; + return MI == mMap.end() ? -1 : (int)MI->second; } @@ -397,7 +352,7 @@ int SlotTracker::getLocalSlot(const Value *V) { initialize(); ValueMap::iterator FI = fMap.find(V); - return FI == fMap.end() ? -1 : FI->second; + return FI == fMap.end() ? -1 : (int)FI->second; } @@ -532,11 +487,12 @@ static void calcTypeName(const Type *Ty, Result += "{ "; for (StructType::element_iterator I = STy->element_begin(), E = STy->element_end(); I != E; ++I) { - if (I != STy->element_begin()) - Result += ", "; calcTypeName(*I, TypeStack, TypeNames, Result); + if (next(I) != STy->element_end()) + Result += ','; + Result += ' '; } - Result += " }"; + Result += '}'; if (STy->isPacked()) Result += '>'; break; @@ -631,21 +587,6 @@ void llvm::WriteTypeSymbolic(raw_ostream &Out, const Type *Ty, const Module *M){ } } -// 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) { - for (unsigned i = 0, e = Str.size(); i != e; ++i) { - unsigned char C = Str[i]; - if (isprint(C) && C != '"' && C != '\\') { - Out << C; - } else { - Out << '\\' - << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')) - << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); - } - } -} - static const char *getPredicateText(unsigned predicate) { const char * pred = "unknown"; switch (predicate) { @@ -699,6 +640,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, // make sure that we only output it in exponential format if we can parse // the value back and get the same value. // + bool ignored; bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble; double Val = isDouble ? CFP->getValueAPF().convertToDouble() : CFP->getValueAPF().convertToFloat(); @@ -718,10 +660,20 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, } } // Otherwise we could not reparse it to exactly the same value, so we must - // output the string in hexadecimal format! + // output the string in hexadecimal format! Note that loading and storing + // floating point types changes the bits of NaNs on some hosts, notably + // x86, so we must not use these types. assert(sizeof(double) == sizeof(uint64_t) && "assuming that double is 64 bits!"); - Out << "0x" << utohexstr(DoubleToBits(Val)); + char Buffer[40]; + APFloat apf = CFP->getValueAPF(); + // Floats are represented in ASCII IR as double, convert. + if (!isDouble) + apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, + &ignored); + Out << "0x" << + utohex_buffer(uint64_t(apf.bitcastToAPInt().getZExtValue()), + Buffer+40); return; } @@ -737,7 +689,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, else assert(0 && "Unsupported floating point type"); // api needed to prevent premature destruction - APInt api = CFP->getValueAPF().convertToAPInt(); + APInt api = CFP->getValueAPF().bitcastToAPInt(); const uint64_t* p = api.getRawData(); uint64_t word = *p; int shiftcount=60; @@ -775,7 +727,6 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, } else { // Cannot output in string format... Out << '['; if (CA->getNumOperands()) { - Out << ' '; printTypeInt(Out, ETy, TypeTable); Out << ' '; WriteAsOperandInternal(Out, CA->getOperand(0), @@ -786,7 +737,6 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << ' '; WriteAsOperandInternal(Out, CA->getOperand(i), TypeTable, Machine); } - Out << ' '; } Out << ']'; } @@ -825,7 +775,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, const Type *ETy = CP->getType()->getElementType(); assert(CP->getNumOperands() > 0 && "Number of operands for a PackedConst must be > 0"); - Out << "< "; + Out << '<'; printTypeInt(Out, ETy, TypeTable); Out << ' '; WriteAsOperandInternal(Out, CP->getOperand(0), TypeTable, Machine); @@ -835,7 +785,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << ' '; WriteAsOperandInternal(Out, CP->getOperand(i), TypeTable, Machine); } - Out << " >"; + Out << '>'; return; } @@ -1006,7 +956,7 @@ public: void write(const Type *Ty) { printType(Ty); } void writeOperand(const Value *Op, bool PrintType); - void writeParamOperand(const Value *Operand, ParameterAttributes Attrs); + void writeParamOperand(const Value *Operand, Attributes Attrs); const Module* getModule() { return TheModule; } @@ -1016,7 +966,7 @@ private: void printGlobal(const GlobalVariable *GV); void printAlias(const GlobalAlias *GV); void printFunction(const Function *F); - void printArgument(const Argument *FA, ParameterAttributes Attrs); + void printArgument(const Argument *FA, Attributes Attrs); void printBasicBlock(const BasicBlock *BB); void printInstruction(const Instruction &I); @@ -1126,15 +1076,15 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { } void AssemblyWriter::writeParamOperand(const Value *Operand, - ParameterAttributes Attrs) { + Attributes Attrs) { if (Operand == 0) { Out << ""; } else { // Print the type printType(Operand->getType()); // Print parameter attributes list - if (Attrs != ParamAttr::None) - Out << ' ' << ParamAttr::getAsString(Attrs); + if (Attrs != Attribute::None) + Out << ' ' << Attribute::getAsString(Attrs); Out << ' '; // Print the operand WriteAsOperandInternal(Out, Operand, TypeNames, &Machine); @@ -1207,6 +1157,7 @@ void AssemblyWriter::printModule(const Module *M) { static void PrintLinkage(GlobalValue::LinkageTypes LT, raw_ostream &Out) { switch (LT) { + case GlobalValue::PrivateLinkage: Out << "private "; break; case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break; case GlobalValue::WeakLinkage: Out << "weak "; break; @@ -1246,6 +1197,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { PrintVisibility(GV->getVisibility(), Out); if (GV->isThreadLocal()) Out << "thread_local "; + if (unsigned AddressSpace = GV->getType()->getAddressSpace()) + Out << "addrspace(" << AddressSpace << ") "; Out << (GV->isConstant() ? "constant " : "global "); printType(GV->getType()->getElementType()); @@ -1253,9 +1206,6 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { Out << ' '; writeOperand(GV->getInitializer(), false); } - - if (unsigned AddressSpace = GV->getType()->getAddressSpace()) - Out << " addrspace(" << AddressSpace << ") "; if (GV->hasSection()) Out << ", section \"" << GV->getSection() << '"'; @@ -1290,10 +1240,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { printType(F->getFunctionType()); Out << "* "; - if (F->hasName()) - PrintLLVMName(Out, F); - else - Out << "@\"\""; + WriteAsOperandInternal(Out, F, TypeNames, &Machine); } else if (const GlobalAlias *GA = dyn_cast(Aliasee)) { printType(GA->getType()); Out << " "; @@ -1350,18 +1297,17 @@ void AssemblyWriter::printFunction(const Function *F) { 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_SSECall: Out << "x86_ssecallcc "; break; default: Out << "cc" << F->getCallingConv() << " "; break; } const FunctionType *FT = F->getFunctionType(); - const PAListPtr &Attrs = F->getParamAttrs(); + const AttrListPtr &Attrs = F->getAttributes(); + Attributes RetAttrs = Attrs.getRetAttributes(); + if (RetAttrs != Attribute::None) + Out << Attribute::getAsString(Attrs.getRetAttributes()) << ' '; printType(F->getReturnType()); Out << ' '; - if (F->hasName()) - PrintLLVMName(Out, F); - else - Out << "@\"\""; + WriteAsOperandInternal(Out, F, TypeNames, &Machine); Out << '('; Machine.incorporateFunction(F); @@ -1374,7 +1320,7 @@ void AssemblyWriter::printFunction(const Function *F) { I != E; ++I) { // Insert commas as we go... the first arg doesn't get a comma if (I != F->arg_begin()) Out << ", "; - printArgument(I, Attrs.getParamAttrs(Idx)); + printArgument(I, Attrs.getParamAttributes(Idx)); Idx++; } } else { @@ -1386,9 +1332,9 @@ void AssemblyWriter::printFunction(const Function *F) { // Output type... printType(FT->getParamType(i)); - ParameterAttributes ArgAttrs = Attrs.getParamAttrs(i+1); - if (ArgAttrs != ParamAttr::None) - Out << ' ' << ParamAttr::getAsString(ArgAttrs); + Attributes ArgAttrs = Attrs.getParamAttributes(i+1); + if (ArgAttrs != Attribute::None) + Out << ' ' << Attribute::getAsString(ArgAttrs); } } @@ -1398,34 +1344,15 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "..."; // Output varargs portion of signature! } Out << ')'; - ParameterAttributes RetAttrs = Attrs.getParamAttrs(0); - if (RetAttrs != ParamAttr::None) - Out << ' ' << ParamAttr::getAsString(Attrs.getParamAttrs(0)); + Attributes FnAttrs = Attrs.getFnAttributes(); + if (FnAttrs != Attribute::None) + Out << ' ' << Attribute::getAsString(Attrs.getFnAttributes()); if (F->hasSection()) Out << " section \"" << F->getSection() << '"'; if (F->getAlignment()) Out << " align " << F->getAlignment(); if (F->hasGC()) Out << " gc \"" << F->getGC() << '"'; - FunctionNotes FNotes = F->getNotes(); - if (FNotes != FN_NOTE_None) { - Out << " notes("; - bool NeedComma = false; - if (FNotes & FN_NOTE_AlwaysInline) { - NeedComma = true; - Out << "inline=always"; - } - else if (FNotes & FN_NOTE_NoInline) { - NeedComma = true; - Out << "inline=never"; - } - if (FNotes & FN_NOTE_OptimizeForSize) { - if (NeedComma) - Out << ","; - Out << "opt_size"; - } - Out << ")"; - } if (F->isDeclaration()) { Out << "\n"; } else { @@ -1445,13 +1372,13 @@ void AssemblyWriter::printFunction(const Function *F) { /// the function. Simply print it out /// void AssemblyWriter::printArgument(const Argument *Arg, - ParameterAttributes Attrs) { + Attributes Attrs) { // Output type... printType(Arg->getType()); // Output parameter attributes list - if (Attrs != ParamAttr::None) - Out << ' ' << ParamAttr::getAsString(Attrs); + if (Attrs != Attribute::None) + Out << ' ' << Attribute::getAsString(Attrs); // Output name, if available... if (Arg->hasName()) { @@ -1570,13 +1497,14 @@ void AssemblyWriter::printInstruction(const Instruction &I) { const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0; // Special case conditional branches to swizzle the condition out to the front - if (isa(I) && I.getNumOperands() > 1) { + if (isa(I) && cast(I).isConditional()) { + BranchInst &BI(cast(I)); Out << ' '; - writeOperand(I.getOperand(2), true); + writeOperand(BI.getCondition(), true); Out << ", "; - writeOperand(Operand, true); + writeOperand(BI.getSuccessor(0), true); Out << ", "; - writeOperand(I.getOperand(1), true); + writeOperand(BI.getSuccessor(1), true); } else if (isa(I)) { // Special case switch statement to get formatting nice and correct... @@ -1625,14 +1553,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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_SSECall: Out << " x86_ssecallcc"; 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 PAListPtr &PAL = CI->getParamAttrs(); + const AttrListPtr &PAL = CI->getAttributes(); + + if (PAL.getRetAttributes() != Attribute::None) + Out << ' ' << Attribute::getAsString(PAL.getRetAttributes()); // 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, @@ -1652,16 +1582,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 1) Out << ", "; - writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op)); + writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op)); } Out << ')'; - if (PAL.getParamAttrs(0) != ParamAttr::None) - Out << ' ' << ParamAttr::getAsString(PAL.getParamAttrs(0)); + if (PAL.getFnAttributes() != Attribute::None) + Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); } else if (const InvokeInst *II = dyn_cast(&I)) { const PointerType *PTy = cast(Operand->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - const PAListPtr &PAL = II->getParamAttrs(); + const AttrListPtr &PAL = II->getAttributes(); // Print the calling convention being used. switch (II->getCallingConv()) { @@ -1670,34 +1600,37 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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_SSECall: Out << " x86_ssecallcc"; break; default: Out << " cc" << II->getCallingConv(); break; } + if (PAL.getRetAttributes() != Attribute::None) + Out << ' ' << Attribute::getAsString(PAL.getRetAttributes()); + // If possible, print out the short form of the invoke instruction. We can // only do this if the first argument is a pointer to a nonvararg function, // and if the return type is not a pointer to a function. // + Out << ' '; if (!FTy->isVarArg() && (!isa(RetTy) || !isa(cast(RetTy)->getElementType()))) { - Out << ' '; printType(RetTy); + printType(RetTy); + Out << ' '; writeOperand(Operand, false); } else { - Out << ' '; writeOperand(Operand, true); } - Out << '('; for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 3) Out << ", "; - writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op-2)); + writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op-2)); } Out << ')'; - if (PAL.getParamAttrs(0) != ParamAttr::None) - Out << ' ' << ParamAttr::getAsString(PAL.getParamAttrs(0)); + if (PAL.getFnAttributes() != Attribute::None) + Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); + Out << "\n\t\t\tto "; writeOperand(II->getNormalDest(), true); Out << " unwind "; @@ -1742,7 +1675,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } else { for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) { Operand = I.getOperand(i); - if (Operand->getType() != TheType) { + // note that Operand shouldn't be null, but the test helps make dump() + // more tolerant of malformed IR + if (Operand && Operand->getType() != TheType) { PrintAllTypes = true; // We have differing types! Print them all! break; } @@ -1820,7 +1755,7 @@ void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { AssemblyWriter W(OS, SlotTable, GV->getParent(), 0); W.write(GV); } else if (const Constant *C = dyn_cast(this)) { - OS << ' ' << C->getType()->getDescription() << ' '; + OS << C->getType()->getDescription() << ' '; std::map TypeTable; WriteConstantInt(OS, C, TypeTable, 0); } else if (const Argument *A = dyn_cast(this)) { @@ -1829,8 +1764,7 @@ void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { } else if (isa(this)) { WriteAsOperand(OS, this, true, 0); } else { - // FIXME: PseudoSourceValue breaks this! - //assert(0 && "Unknown value to print out!"); + assert(0 && "Unknown value to print out!"); } } @@ -1845,6 +1779,14 @@ void Value::dump() const { print(errs()); errs() << '\n'; errs().flush(); } // Type::dump - allow easy printing of Types from the debugger. void Type::dump() const { print(errs()); errs() << '\n'; errs().flush(); } +// Type::dump - allow easy printing of Types from the debugger. +// This one uses type names from the given context module +void Type::dump(const Module *Context) const { + WriteTypeSymbolic(errs(), this, Context); + errs() << '\n'; + errs().flush(); +} + // Module::dump() - Allow printing of Modules from the debugger. void Module::dump() const { print(errs(), 0); errs().flush(); }