X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FAsmWriter.cpp;h=68cf438e29a55ab9c90ac5789e8ea860845023d0;hb=b5bd026a756d8650f2a94607c9b1dc34cf1c024a;hp=cd7b8a675d2b52df53c2c1784cc2df85551e90ab;hpb=ab49ee752ec37f586e45c999eca1e29e32697cb7;p=oota-llvm.git diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index cd7b8a675d2..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,17 +727,18 @@ 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), TypeTable, Machine); for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { Out << ", "; printTypeInt(Out, ETy, TypeTable); + Out << ' '; WriteAsOperandInternal(Out, CA->getOperand(i), TypeTable, Machine); } } - Out << " ]"; + Out << ']'; } return; } @@ -798,18 +751,21 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, if (N) { Out << ' '; printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable); + Out << ' '; WriteAsOperandInternal(Out, CS->getOperand(0), TypeTable, Machine); for (unsigned i = 1; i < N; i++) { Out << ", "; printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable); + Out << ' '; WriteAsOperandInternal(Out, CS->getOperand(i), TypeTable, Machine); } + Out << ' '; } - Out << " }"; + Out << '}'; if (CS->getType()->isPacked()) Out << '>'; return; @@ -819,15 +775,17 @@ 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); for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { Out << ", "; printTypeInt(Out, ETy, TypeTable); + Out << ' '; WriteAsOperandInternal(Out, CP->getOperand(i), TypeTable, Machine); } - Out << " >"; + Out << '>'; return; } @@ -849,6 +807,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) { printTypeInt(Out, (*OI)->getType(), TypeTable); + Out << ' '; WriteAsOperandInternal(Out, *OI, TypeTable, Machine); if (OI+1 != CE->op_end()) Out << ", "; @@ -880,7 +839,6 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, std::map &TypeTable, SlotTracker *Machine) { - Out << ' '; if (V->hasName()) { PrintLLVMName(Out, V); return; @@ -952,8 +910,10 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, bool PrintType, if (Context) fillTypeNameTable(Context, TypeNames); - if (PrintType) + if (PrintType) { printTypeInt(Out, V->getType(), TypeNames); + Out << ' '; + } WriteAsOperandInternal(Out, V, TypeNames, 0); } @@ -996,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; } @@ -1006,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); @@ -1108,24 +1068,24 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { Out << ""; } else { if (PrintType) { - Out << ' '; printType(Operand->getType()); + Out << ' '; } WriteAsOperandInternal(Out, Operand, TypeNames, &Machine); } } void AssemblyWriter::writeParamOperand(const Value *Operand, - ParameterAttributes Attrs) { + Attributes Attrs) { if (Operand == 0) { Out << ""; } else { - Out << ' '; // 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); } @@ -1197,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; @@ -1236,14 +1197,15 @@ 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()); - if (GV->hasInitializer()) + if (GV->hasInitializer()) { + Out << ' '; writeOperand(GV->getInitializer(), false); - - if (unsigned AddressSpace = GV->getType()->getAddressSpace()) - Out << " addrspace(" << AddressSpace << ") "; + } if (GV->hasSection()) Out << ", section \"" << GV->getSection() << '"'; @@ -1278,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 << " "; @@ -1338,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); @@ -1362,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 { @@ -1374,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); } } @@ -1386,16 +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() << '"'; - if (F->isDeclaration()) { Out << "\n"; } else { @@ -1415,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()) { @@ -1456,10 +1413,10 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (PI == PE) { Out << " No predecessors!"; } else { - Out << " preds ="; + Out << " preds = "; writeOperand(*PI, false); for (++PI; PI != PE; ++PI) { - Out << ','; + Out << ", "; writeOperand(*PI, false); } } @@ -1486,7 +1443,7 @@ void AssemblyWriter::printInfoComment(const Value &V) { printType(V.getType()); Out << '>'; - if (!V.hasName()) { + if (!V.hasName() && !isa(V)) { int SlotNum; if (const GlobalValue *GV = dyn_cast(&V)) SlotNum = Machine.getGlobalSlot(GV); @@ -1511,6 +1468,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (I.hasName()) { PrintLLVMName(Out, &I); Out << " = "; + } else if (I.getType() != Type::VoidTy) { + // Print out the def slot taken. + int SlotNum = Machine.getLocalSlot(&I); + if (SlotNum == -1) + Out << " = "; + else + Out << '%' << SlotNum << " = "; } // If this is a volatile load or store, print out the volatile marker. @@ -1533,24 +1497,27 @@ 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) { - writeOperand(I.getOperand(2), true); - Out << ','; - writeOperand(Operand, true); - Out << ','; - writeOperand(I.getOperand(1), true); + if (isa(I) && cast(I).isConditional()) { + BranchInst &BI(cast(I)); + Out << ' '; + writeOperand(BI.getCondition(), true); + Out << ", "; + writeOperand(BI.getSuccessor(0), true); + Out << ", "; + writeOperand(BI.getSuccessor(1), true); } else if (isa(I)) { // Special case switch statement to get formatting nice and correct... + Out << ' '; writeOperand(Operand , true); - Out << ','; + Out << ", "; writeOperand(I.getOperand(1), true); Out << " ["; for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) { Out << "\n\t\t"; writeOperand(I.getOperand(op ), true); - Out << ','; + Out << ", "; writeOperand(I.getOperand(op+1), true); } Out << "\n\t]"; @@ -1561,16 +1528,18 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) { if (op) Out << ", "; - Out << '['; - writeOperand(I.getOperand(op ), false); Out << ','; + Out << "[ "; + writeOperand(I.getOperand(op ), false); Out << ", "; writeOperand(I.getOperand(op+1), false); Out << " ]"; } } else if (const ExtractValueInst *EVI = dyn_cast(&I)) { + Out << ' '; writeOperand(I.getOperand(0), true); for (const unsigned *i = EVI->idx_begin(), *e = EVI->idx_end(); i != e; ++i) Out << ", " << *i; } else if (const InsertValueInst *IVI = dyn_cast(&I)) { - writeOperand(I.getOperand(0), true); Out << ','; + Out << ' '; + writeOperand(I.getOperand(0), true); Out << ", "; writeOperand(I.getOperand(1), true); for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i) Out << ", " << *i; @@ -1584,23 +1553,27 @@ 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, // 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 { writeOperand(Operand, true); @@ -1608,73 +1581,83 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << '('; for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 1) - Out << ','; - writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op)); + Out << ", "; + writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op)); } - Out << " )"; - if (PAL.getParamAttrs(0) != ParamAttr::None) - Out << ' ' << ParamAttr::getAsString(PAL.getParamAttrs(0)); + Out << ')'; + 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()) { 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_SSECall: Out << "x86_ssecallcc "; break; + case CallingConv::X86_StdCall: Out << " x86_stdcallcc"; break; + case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; 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 { 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)); + Out << ", "; + writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op-2)); } - Out << " )"; - if (PAL.getParamAttrs(0) != ParamAttr::None) - Out << ' ' << ParamAttr::getAsString(PAL.getParamAttrs(0)); - Out << "\n\t\t\tto"; + Out << ')'; + if (PAL.getFnAttributes() != Attribute::None) + Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); + + Out << "\n\t\t\tto "; writeOperand(II->getNormalDest(), true); - Out << " unwind"; + Out << " unwind "; writeOperand(II->getUnwindDest(), true); } else if (const AllocationInst *AI = dyn_cast(&I)) { Out << ' '; printType(AI->getType()->getElementType()); if (AI->isArrayAllocation()) { - Out << ','; + Out << ", "; writeOperand(AI->getArraySize(), true); } if (AI->getAlignment()) { Out << ", align " << AI->getAlignment(); } } else if (isa(I)) { - if (Operand) writeOperand(Operand, true); // Work with broken code + if (Operand) { + Out << ' '; + writeOperand(Operand, true); // Work with broken code + } Out << " to "; printType(I.getType()); } else if (isa(I)) { - if (Operand) writeOperand(Operand, true); // Work with broken code + if (Operand) { + Out << ' '; + writeOperand(Operand, true); // Work with broken code + } Out << ", "; printType(I.getType()); } else if (Operand) { // Print the normal way... @@ -1692,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; } @@ -1704,8 +1689,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { printType(TheType); } + Out << ' '; for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) { - if (i) Out << ','; + if (i) Out << ", "; writeOperand(I.getOperand(i), PrintAllTypes); } } @@ -1769,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)) { @@ -1787,15 +1773,21 @@ void Value::print(std::ostream &O, AssemblyAnnotationWriter *AAW) const { print(OS, AAW); } -// Value::dump - allow easy printing of Values from the debugger. -// Located here because so much of the needed functionality is here. -void Value::dump() const { print(errs()); errs() << '\n'; } +// Value::dump - allow easy printing of Values from the debugger. +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 Values from the debugger. -// Located here because so much of the needed functionality is here. -void Type::dump() const { print(errs()); errs() << '\n'; } +// 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 from debugger -void Module::dump() const { print(errs(), 0); } +// Module::dump() - Allow printing of Modules from the debugger. +void Module::dump() const { print(errs(), 0); errs().flush(); }