X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FAsmWriter.cpp;h=68cf438e29a55ab9c90ac5789e8ea860845023d0;hb=b5bd026a756d8650f2a94607c9b1dc34cf1c024a;hp=e1869859ec2f3f53e8869296dac0372836386e71;hpb=19c874638d9478a5d5028854817a5ee72293bb2b;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index e1869859ec2..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("print-module", "Print module to stderr"); -char PrintFunctionPass::ID = 0; -static RegisterPass -Y("print-function","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; } @@ -632,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) { @@ -700,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(); @@ -719,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; } @@ -738,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; @@ -776,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), @@ -787,7 +737,6 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << ' '; WriteAsOperandInternal(Out, CA->getOperand(i), TypeTable, Machine); } - Out << ' '; } Out << ']'; } @@ -826,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); @@ -836,7 +785,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << ' '; WriteAsOperandInternal(Out, CP->getOperand(i), TypeTable, Machine); } - Out << " >"; + Out << '>'; return; } @@ -1208,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; @@ -1247,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()); @@ -1254,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() << '"'; @@ -1291,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 << " "; @@ -1356,12 +1302,12 @@ void AssemblyWriter::printFunction(const Function *F) { const FunctionType *FT = F->getFunctionType(); 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); @@ -1398,9 +1344,6 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "..."; // Output varargs portion of signature! } Out << ')'; - Attributes RetAttrs = Attrs.getRetAttributes(); - if (RetAttrs != Attribute::None) - Out << ' ' << Attribute::getAsString(Attrs.getRetAttributes()); Attributes FnAttrs = Attrs.getFnAttributes(); if (FnAttrs != Attribute::None) Out << ' ' << Attribute::getAsString(Attrs.getFnAttributes()); @@ -1413,34 +1356,6 @@ void AssemblyWriter::printFunction(const Function *F) { if (F->isDeclaration()) { Out << "\n"; } else { - - bool insideNotes = false; - if (F->hasNote(Attribute::AlwaysInline)) { - Out << " notes("; - insideNotes = true; - Out << "inline=always"; - } - if (F->hasNote(Attribute::NoInline)) { - if (insideNotes) - Out << ","; - else { - Out << " notes("; - insideNotes = true; - } - Out << "inline=never"; - } - if (F->hasNote(Attribute::OptimizeForSize)) { - if (insideNotes) - Out << ","; - else { - Out << " notes("; - insideNotes = true; - } - Out << "opt_size"; - } - if (insideNotes) - Out << ")"; - Out << " {"; // Output all of its basic blocks... for the function @@ -1582,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... @@ -1645,6 +1561,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { const Type *RetTy = FTy->getReturnType(); 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, // and if the return type is not a pointer to a function. @@ -1666,8 +1585,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op)); } Out << ')'; - if (PAL.getRetAttributes() != Attribute::None) - Out << ' ' << Attribute::getAsString(PAL.getRetAttributes()); if (PAL.getFnAttributes() != Attribute::None) Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); } else if (const InvokeInst *II = dyn_cast(&I)) { @@ -1686,20 +1603,23 @@ void AssemblyWriter::printInstruction(const Instruction &I) { 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) @@ -1708,8 +1628,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } Out << ')'; - if (PAL.getRetAttributes() != Attribute::None) - Out << ' ' << Attribute::getAsString(PAL.getRetAttributes()); if (PAL.getFnAttributes() != Attribute::None) Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); @@ -1757,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; } @@ -1835,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)) { @@ -1844,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!"); } } @@ -1860,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(); }