#include "llvm/Assembly/Writer.h"
#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Assembly/AsmAnnotationWriter.h"
+#include "llvm/Assembly/AssemblyAnnotationWriter.h"
#include "llvm/LLVMContext.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/Operator.h"
#include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h"
-#include "llvm/TypeSymbolTable.h"
-#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FormattedStream.h"
#include <algorithm>
#include <cctype>
-#include <map>
using namespace llvm;
// Make virtual table appear in this compilation unit.
const Function *M = I->getParent() ? I->getParent()->getParent() : 0;
return M ? M->getParent() : 0;
}
-
+
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
return GV->getParent();
- if (const NamedMDNode *NMD = dyn_cast<NamedMDNode>(V))
- return NMD->getParent();
return 0;
}
// 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 StringRef &Name,
- raw_ostream &Out) {
+static void PrintEscapedString(StringRef Name, raw_ostream &Out) {
for (unsigned i = 0, e = Name.size(); i != e; ++i) {
unsigned char C = Name[i];
if (isprint(C) && C != '\\' && C != '"')
/// 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.
-static void PrintLLVMName(raw_ostream &OS, const StringRef &Name,
- PrefixType Prefix) {
- assert(Name.data() && "Cannot get empty name!");
+static void PrintLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix) {
+ assert(!Name.empty() && "Cannot get empty name!");
switch (Prefix) {
default: llvm_unreachable("Bad prefix!");
case NoPrefix: break;
// TypePrinting Class: Type printing machinery
//===----------------------------------------------------------------------===//
-static DenseMap<const Type *, std::string> &getTypeNamesMap(void *M) {
- return *static_cast<DenseMap<const Type *, std::string>*>(M);
-}
+/// TypePrinting - Type printing machinery.
+namespace {
+class TypePrinting {
+ TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT
+ void operator=(const TypePrinting&); // DO NOT IMPLEMENT
+public:
-void TypePrinting::clear() {
- getTypeNamesMap(TypeNames).clear();
-}
+ /// NamedTypes - The named types that are used by the current module.
+ std::vector<StructType*> NamedTypes;
-bool TypePrinting::hasTypeName(const Type *Ty) const {
- return getTypeNamesMap(TypeNames).count(Ty);
-}
+ /// NumberedTypes - The numbered types, along with their value.
+ DenseMap<StructType*, unsigned> NumberedTypes;
-void TypePrinting::addTypeName(const Type *Ty, const std::string &N) {
- getTypeNamesMap(TypeNames).insert(std::make_pair(Ty, N));
-}
+ TypePrinting() {}
+ ~TypePrinting() {}
-TypePrinting::TypePrinting() {
- TypeNames = new DenseMap<const Type *, std::string>();
-}
+ void incorporateTypes(const Module &M);
-TypePrinting::~TypePrinting() {
- delete &getTypeNamesMap(TypeNames);
-}
+ void print(Type *Ty, raw_ostream &OS);
-/// CalcTypeName - Write the specified type to the specified raw_ostream, making
-/// use of type names or up references to shorten the type name where possible.
-void TypePrinting::CalcTypeName(const Type *Ty,
- SmallVectorImpl<const Type *> &TypeStack,
- raw_ostream &OS, bool IgnoreTopLevelName) {
- // Check to see if the type is named.
- if (!IgnoreTopLevelName) {
- DenseMap<const Type *, std::string> &TM = getTypeNamesMap(TypeNames);
- DenseMap<const Type *, std::string>::iterator I = TM.find(Ty);
- if (I != TM.end()) {
- OS << I->second;
- return;
- }
- }
+ void printStructBody(StructType *Ty, raw_ostream &OS);
+};
+} // end anonymous namespace.
- // Check to see if the Type is already on the stack...
- unsigned Slot = 0, CurSize = TypeStack.size();
- while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type
- // This is another base case for the recursion. In this case, we know
- // that we have looped back to a type that we have previously visited.
- // Generate the appropriate upreference to handle this.
- if (Slot < CurSize) {
- OS << '\\' << unsigned(CurSize-Slot); // Here's the upreference
- return;
+void TypePrinting::incorporateTypes(const Module &M) {
+ M.findUsedStructTypes(NamedTypes);
+
+ // The list of struct types we got back includes all the struct types, split
+ // the unnamed ones out to a numbering and remove the anonymous structs.
+ unsigned NextNumber = 0;
+
+ std::vector<StructType*>::iterator NextToUse = NamedTypes.begin(), I, E;
+ for (I = NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) {
+ StructType *STy = *I;
+
+ // Ignore anonymous types.
+ if (STy->isLiteral())
+ continue;
+
+ if (STy->getName().empty())
+ NumberedTypes[STy] = NextNumber++;
+ else
+ *NextToUse++ = STy;
}
- TypeStack.push_back(Ty); // Recursive case: Add us to the stack..
+ NamedTypes.erase(NextToUse, NamedTypes.end());
+}
+
+/// CalcTypeName - Write the specified type to the specified raw_ostream, making
+/// use of type names or up references to shorten the type name where possible.
+void TypePrinting::print(Type *Ty, raw_ostream &OS) {
switch (Ty->getTypeID()) {
case Type::VoidTyID: OS << "void"; break;
case Type::FloatTyID: OS << "float"; break;
case Type::PPC_FP128TyID: OS << "ppc_fp128"; break;
case Type::LabelTyID: OS << "label"; break;
case Type::MetadataTyID: OS << "metadata"; break;
+ case Type::X86_MMXTyID: OS << "x86_mmx"; break;
case Type::IntegerTyID:
OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
- break;
+ return;
case Type::FunctionTyID: {
- const FunctionType *FTy = cast<FunctionType>(Ty);
- CalcTypeName(FTy->getReturnType(), TypeStack, OS);
+ FunctionType *FTy = cast<FunctionType>(Ty);
+ print(FTy->getReturnType(), OS);
OS << " (";
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I) {
if (I != FTy->param_begin())
OS << ", ";
- CalcTypeName(*I, TypeStack, OS);
+ print(*I, OS);
}
if (FTy->isVarArg()) {
if (FTy->getNumParams()) OS << ", ";
OS << "...";
}
OS << ')';
- break;
+ return;
}
case Type::StructTyID: {
- const StructType *STy = cast<StructType>(Ty);
- if (STy->isPacked())
- OS << '<';
- OS << "{ ";
- for (StructType::element_iterator I = STy->element_begin(),
- E = STy->element_end(); I != E; ++I) {
- CalcTypeName(*I, TypeStack, OS);
- if (next(I) != STy->element_end())
- OS << ',';
- OS << ' ';
- }
- OS << '}';
- if (STy->isPacked())
- OS << '>';
- break;
- }
- case Type::UnionTyID: {
- const UnionType *UTy = cast<UnionType>(Ty);
- OS << "union { ";
- for (StructType::element_iterator I = UTy->element_begin(),
- E = UTy->element_end(); I != E; ++I) {
- CalcTypeName(*I, TypeStack, OS);
- if (next(I) != UTy->element_end())
- OS << ',';
- OS << ' ';
- }
- OS << '}';
- break;
+ StructType *STy = cast<StructType>(Ty);
+
+ if (STy->isLiteral())
+ return printStructBody(STy, OS);
+
+ if (!STy->getName().empty())
+ return PrintLLVMName(OS, STy->getName(), LocalPrefix);
+
+ DenseMap<StructType*, unsigned>::iterator I = NumberedTypes.find(STy);
+ if (I != NumberedTypes.end())
+ OS << '%' << I->second;
+ else // Not enumerated, print the hex address.
+ OS << "%\"type 0x" << STy << '\"';
+ return;
}
case Type::PointerTyID: {
- const PointerType *PTy = cast<PointerType>(Ty);
- CalcTypeName(PTy->getElementType(), TypeStack, OS);
+ PointerType *PTy = cast<PointerType>(Ty);
+ print(PTy->getElementType(), OS);
if (unsigned AddressSpace = PTy->getAddressSpace())
OS << " addrspace(" << AddressSpace << ')';
OS << '*';
- break;
+ return;
}
case Type::ArrayTyID: {
- const ArrayType *ATy = cast<ArrayType>(Ty);
+ ArrayType *ATy = cast<ArrayType>(Ty);
OS << '[' << ATy->getNumElements() << " x ";
- CalcTypeName(ATy->getElementType(), TypeStack, OS);
+ print(ATy->getElementType(), OS);
OS << ']';
- break;
+ return;
}
case Type::VectorTyID: {
- const VectorType *PTy = cast<VectorType>(Ty);
+ VectorType *PTy = cast<VectorType>(Ty);
OS << "<" << PTy->getNumElements() << " x ";
- CalcTypeName(PTy->getElementType(), TypeStack, OS);
+ print(PTy->getElementType(), OS);
OS << '>';
- break;
+ return;
}
- case Type::OpaqueTyID:
- OS << "opaque";
- break;
default:
OS << "<unrecognized-type>";
- break;
+ return;
}
-
- TypeStack.pop_back(); // Remove self from stack.
}
-/// printTypeInt - The internal guts of printing out a type that has a
-/// potentially named portion.
-///
-void TypePrinting::print(const Type *Ty, raw_ostream &OS,
- bool IgnoreTopLevelName) {
- // Check to see if the type is named.
- DenseMap<const Type*, std::string> &TM = getTypeNamesMap(TypeNames);
- if (!IgnoreTopLevelName) {
- DenseMap<const Type*, std::string>::iterator I = TM.find(Ty);
- if (I != TM.end()) {
- OS << I->second;
- return;
- }
+void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
+ if (STy->isOpaque()) {
+ OS << "opaque";
+ return;
}
- // Otherwise we have a type that has not been named but is a derived type.
- // Carefully recurse the type hierarchy to print out any contained symbolic
- // names.
- SmallVector<const Type *, 16> TypeStack;
- std::string TypeName;
-
- raw_string_ostream TypeOS(TypeName);
- CalcTypeName(Ty, TypeStack, TypeOS, IgnoreTopLevelName);
- OS << TypeOS.str();
-
- // Cache type name for later use.
- if (!IgnoreTopLevelName)
- TM.insert(std::make_pair(Ty, TypeOS.str()));
-}
-
-namespace {
- class TypeFinder {
- // To avoid walking constant expressions multiple times and other IR
- // objects, we keep several helper maps.
- DenseSet<const Value*> VisitedConstants;
- DenseSet<const Type*> VisitedTypes;
-
- TypePrinting &TP;
- std::vector<const Type*> &NumberedTypes;
- public:
- TypeFinder(TypePrinting &tp, std::vector<const Type*> &numberedTypes)
- : TP(tp), NumberedTypes(numberedTypes) {}
-
- void Run(const Module &M) {
- // Get types from the type symbol table. This gets opaque types referened
- // only through derived named types.
- const TypeSymbolTable &ST = M.getTypeSymbolTable();
- for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end();
- TI != E; ++TI)
- IncorporateType(TI->second);
-
- // Get types from global variables.
- for (Module::const_global_iterator I = M.global_begin(),
- E = M.global_end(); I != E; ++I) {
- IncorporateType(I->getType());
- if (I->hasInitializer())
- IncorporateValue(I->getInitializer());
- }
-
- // Get types from aliases.
- for (Module::const_alias_iterator I = M.alias_begin(),
- E = M.alias_end(); I != E; ++I) {
- IncorporateType(I->getType());
- IncorporateValue(I->getAliasee());
- }
-
- // Get types from functions.
- for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
- IncorporateType(FI->getType());
-
- for (Function::const_iterator BB = FI->begin(), E = FI->end();
- BB != E;++BB)
- for (BasicBlock::const_iterator II = BB->begin(),
- E = BB->end(); II != E; ++II) {
- const Instruction &I = *II;
- // Incorporate the type of the instruction and all its operands.
- IncorporateType(I.getType());
- for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
- OI != OE; ++OI)
- IncorporateValue(*OI);
- }
- }
- }
-
- private:
- void IncorporateType(const Type *Ty) {
- // Check to see if we're already visited this type.
- if (!VisitedTypes.insert(Ty).second)
- return;
-
- // If this is a structure or opaque type, add a name for the type.
- if (((Ty->isStructTy() && cast<StructType>(Ty)->getNumElements())
- || Ty->isOpaqueTy()) && !TP.hasTypeName(Ty)) {
- TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size())));
- NumberedTypes.push_back(Ty);
- }
-
- // Recursively walk all contained types.
- for (Type::subtype_iterator I = Ty->subtype_begin(),
- E = Ty->subtype_end(); I != E; ++I)
- IncorporateType(*I);
- }
+ if (STy->isPacked())
+ OS << '<';
- /// IncorporateValue - This method is used to walk operand lists finding
- /// types hiding in constant expressions and other operands that won't be
- /// walked in other ways. GlobalValues, basic blocks, instructions, and
- /// inst operands are all explicitly enumerated.
- void IncorporateValue(const Value *V) {
- if (V == 0 || !isa<Constant>(V) || isa<GlobalValue>(V)) return;
-
- // Already visited?
- if (!VisitedConstants.insert(V).second)
- return;
-
- // Check this type.
- IncorporateType(V->getType());
-
- // Look in operands for types.
- const Constant *C = cast<Constant>(V);
- for (Constant::const_op_iterator I = C->op_begin(),
- E = C->op_end(); I != E;++I)
- IncorporateValue(*I);
- }
- };
-} // end anonymous namespace
-
-
-/// AddModuleTypesToPrinter - Add all of the symbolic type names for types in
-/// the specified module to the TypePrinter and all numbered types to it and the
-/// NumberedTypes table.
-static void AddModuleTypesToPrinter(TypePrinting &TP,
- std::vector<const Type*> &NumberedTypes,
- const Module *M) {
- if (M == 0) return;
-
- // If the module has a symbol table, take all global types and stuff their
- // names into the TypeNames map.
- const TypeSymbolTable &ST = M->getTypeSymbolTable();
- for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end();
- TI != E; ++TI) {
- const Type *Ty = cast<Type>(TI->second);
-
- // As a heuristic, don't insert pointer to primitive types, because
- // they are used too often to have a single useful name.
- if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
- const Type *PETy = PTy->getElementType();
- if ((PETy->isPrimitiveType() || PETy->isIntegerTy()) &&
- !PETy->isOpaqueTy())
- continue;
+ if (STy->getNumElements() == 0) {
+ OS << "{}";
+ } else {
+ StructType::element_iterator I = STy->element_begin();
+ OS << "{ ";
+ print(*I++, OS);
+ for (StructType::element_iterator E = STy->element_end(); I != E; ++I) {
+ OS << ", ";
+ print(*I, OS);
}
- // Likewise don't insert primitives either.
- if (Ty->isIntegerTy() || Ty->isPrimitiveType())
- continue;
-
- // Get the name as a string and insert it into TypeNames.
- std::string NameStr;
- raw_string_ostream NameROS(NameStr);
- formatted_raw_ostream NameOS(NameROS);
- PrintLLVMName(NameOS, TI->first, LocalPrefix);
- NameOS.flush();
- TP.addTypeName(Ty, NameStr);
+ OS << " }";
}
-
- // Walk the entire module to find references to unnamed structure and opaque
- // types. This is required for correctness by opaque types (because multiple
- // uses of an unnamed opaque type needs to be referred to by the same ID) and
- // it shrinks complex recursive structure types substantially in some cases.
- TypeFinder(TP, NumberedTypes).Run(*M);
+ if (STy->isPacked())
+ OS << '>';
}
-/// WriteTypeSymbolic - This attempts to write the specified type as a symbolic
-/// type, iff there is an entry in the modules symbol table for the specified
-/// type or one of it's component types.
-///
-void llvm::WriteTypeSymbolic(raw_ostream &OS, const Type *Ty, const Module *M) {
- TypePrinting Printer;
- std::vector<const Type*> NumberedTypes;
- AddModuleTypesToPrinter(Printer, NumberedTypes, M);
- Printer.print(Ty, OS);
-}
//===----------------------------------------------------------------------===//
// SlotTracker Class: Enumerate slot numbers for unnamed values
const Function* TheFunction;
bool FunctionProcessed;
- /// mMap - The TypePlanes map for the module level data.
+ /// mMap - The slot map for the module level data.
ValueMap mMap;
unsigned mNext;
- /// fMap - The TypePlanes map for the function level data.
+ /// fMap - The slot map for the function level data.
ValueMap fMap;
unsigned fNext;
return new SlotTracker(FA->getParent());
if (const Instruction *I = dyn_cast<Instruction>(V))
- return new SlotTracker(I->getParent()->getParent());
+ if (I->getParent())
+ return new SlotTracker(I->getParent()->getParent());
if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
return new SlotTracker(BB->getParent());
if (const Function *Func = dyn_cast<Function>(V))
return new SlotTracker(Func);
- if (isa<MDNode>(V))
+ if (const MDNode *MD = dyn_cast<MDNode>(V)) {
+ if (!MD->isFunctionLocal())
+ return new SlotTracker(MD->getFunction());
+
return new SlotTracker((Function *)0);
+ }
return 0;
}
// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
SlotTracker::SlotTracker(const Module *M)
- : TheModule(M), TheFunction(0), FunctionProcessed(false),
+ : TheModule(M), TheFunction(0), FunctionProcessed(false),
mNext(0), fNext(0), mdnNext(0) {
}
I = TheModule->named_metadata_begin(),
E = TheModule->named_metadata_end(); I != E; ++I) {
const NamedMDNode *NMD = I;
- for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
- if (MDNode *MD = NMD->getOperand(i))
- CreateMetadataSlot(MD);
- }
+ for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
+ CreateMetadataSlot(NMD->getOperand(i));
}
// Add all the unnamed functions to the table.
E = TheFunction->end(); BB != E; ++BB) {
if (!BB->hasName())
CreateFunctionSlot(BB);
-
+
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E;
++I) {
if (!I->getType()->isVoidTy() && !I->hasName())
CreateFunctionSlot(I);
-
- // Intrinsics can directly use metadata.
- if (isa<IntrinsicInst>(I))
- for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
- if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i)))
- CreateMetadataSlot(N);
+
+ // Intrinsics can directly use metadata. We allow direct calls to any
+ // llvm.foo function here, because the target may not be linked into the
+ // optimizer.
+ if (const CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (Function *F = CI->getCalledFunction())
+ if (F->getName().startswith("llvm."))
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+ if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i)))
+ CreateMetadataSlot(N);
+ }
// Process metadata attached with this instruction.
I->getAllMetadata(MDForInst);
// Check for uninitialized state and do lazy initialization.
initialize();
- // Find the type plane in the module map
+ // Find the value in the module map
ValueMap::iterator MI = mMap.find(V);
return MI == mMap.end() ? -1 : (int)MI->second;
}
// Check for uninitialized state and do lazy initialization.
initialize();
- // Find the type plane in the module map
+ // Find the MDNode in the module map
mdn_iterator MI = mdnMap.find(N);
return MI == mdnMap.end() ? -1 : (int)MI->second;
}
// Don't insert if N is a function-local metadata, these are always printed
// inline.
- if (N->isFunctionLocal())
- return;
-
- mdn_iterator I = mdnMap.find(N);
- if (I != mdnMap.end())
- return;
+ if (!N->isFunctionLocal()) {
+ mdn_iterator I = mdnMap.find(N);
+ if (I != mdnMap.end())
+ return;
- unsigned DestSlot = mdnNext++;
- mdnMap[N] = DestSlot;
+ unsigned DestSlot = mdnNext++;
+ mdnMap[N] = DestSlot;
+ }
// Recursively add any MDNodes referenced by operands.
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
TypePrinting *TypePrinter,
- SlotTracker *Machine);
+ SlotTracker *Machine,
+ const Module *Context);
return pred;
}
+static void writeAtomicRMWOperation(raw_ostream &Out,
+ AtomicRMWInst::BinOp Op) {
+ switch (Op) {
+ default: Out << " <unknown operation " << Op << ">"; break;
+ case AtomicRMWInst::Xchg: Out << " xchg"; break;
+ case AtomicRMWInst::Add: Out << " add"; break;
+ case AtomicRMWInst::Sub: Out << " sub"; break;
+ case AtomicRMWInst::And: Out << " and"; break;
+ case AtomicRMWInst::Nand: Out << " nand"; break;
+ case AtomicRMWInst::Or: Out << " or"; break;
+ case AtomicRMWInst::Xor: Out << " xor"; break;
+ case AtomicRMWInst::Max: Out << " max"; break;
+ case AtomicRMWInst::Min: Out << " min"; break;
+ case AtomicRMWInst::UMax: Out << " umax"; break;
+ case AtomicRMWInst::UMin: Out << " umin"; break;
+ }
+}
static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
if (const OverflowingBinaryOperator *OBO =
Out << " nuw";
if (OBO->hasNoSignedWrap())
Out << " nsw";
- } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) {
+ } else if (const PossiblyExactOperator *Div =
+ dyn_cast<PossiblyExactOperator>(U)) {
if (Div->isExact())
Out << " exact";
} else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
}
}
-static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
- TypePrinting &TypePrinter, SlotTracker *Machine) {
+static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
+ TypePrinting &TypePrinter,
+ SlotTracker *Machine,
+ const Module *Context) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
if (CI->getType()->isIntegerTy(1)) {
Out << (CI->getZExtValue() ? "true" : "false");
Out << "zeroinitializer";
return;
}
-
+
if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
Out << "blockaddress(";
- WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine,
+ Context);
Out << ", ";
- WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine,
+ Context);
Out << ")";
return;
}
// As a special case, print the array as a string if it is an array of
// i8 with ConstantInt values.
//
- const Type *ETy = CA->getType()->getElementType();
+ Type *ETy = CA->getType()->getElementType();
if (CA->isString()) {
Out << "c\"";
PrintEscapedString(CA->getAsString(), Out);
TypePrinter.print(ETy, Out);
Out << ' ';
WriteAsOperandInternal(Out, CA->getOperand(0),
- &TypePrinter, Machine);
+ &TypePrinter, Machine,
+ Context);
for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
Out << ", ";
TypePrinter.print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
+ Context);
}
}
Out << ']';
TypePrinter.print(CS->getOperand(0)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine,
+ Context);
for (unsigned i = 1; i < N; i++) {
Out << ", ";
TypePrinter.print(CS->getOperand(i)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine,
+ Context);
}
Out << ' ';
}
return;
}
- if (const ConstantUnion *CU = dyn_cast<ConstantUnion>(CV)) {
- Out << "{ ";
- TypePrinter.print(CU->getOperand(0)->getType(), Out);
- Out << ' ';
- WriteAsOperandInternal(Out, CU->getOperand(0), &TypePrinter, Machine);
- Out << " }";
- return;
- }
-
if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
- const Type *ETy = CP->getType()->getElementType();
+ Type *ETy = CP->getType()->getElementType();
assert(CP->getNumOperands() > 0 &&
"Number of operands for a PackedConst must be > 0");
Out << '<';
TypePrinter.print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CP->getOperand(0), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CP->getOperand(0), &TypePrinter, Machine,
+ Context);
for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
Out << ", ";
TypePrinter.print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CP->getOperand(i), &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, CP->getOperand(i), &TypePrinter, Machine,
+ Context);
}
Out << '>';
return;
return;
}
- if (const MDNode *Node = dyn_cast<MDNode>(CV)) {
- Out << "!" << Machine->getMetadataSlot(Node);
- return;
- }
-
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
Out << CE->getOpcodeName();
WriteOptimizationInfo(Out, CE);
for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
TypePrinter.print((*OI)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine);
+ WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine, Context);
if (OI+1 != CE->op_end())
Out << ", ";
}
if (CE->hasIndices()) {
- const SmallVector<unsigned, 4> &Indices = CE->getIndices();
+ ArrayRef<unsigned> Indices = CE->getIndices();
for (unsigned i = 0, e = Indices.size(); i != e; ++i)
Out << ", " << Indices[i];
}
static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
TypePrinting *TypePrinter,
- SlotTracker *Machine) {
+ SlotTracker *Machine,
+ const Module *Context) {
Out << "!{";
for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) {
const Value *V = Node->getOperand(mi);
else {
TypePrinter->print(V->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, Node->getOperand(mi),
- TypePrinter, Machine);
+ WriteAsOperandInternal(Out, Node->getOperand(mi),
+ TypePrinter, Machine, Context);
}
if (mi + 1 != me)
Out << ", ";
}
-
+
Out << "}";
}
///
static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
TypePrinting *TypePrinter,
- SlotTracker *Machine) {
+ SlotTracker *Machine,
+ const Module *Context) {
if (V->hasName()) {
PrintLLVMName(Out, V);
return;
const Constant *CV = dyn_cast<Constant>(V);
if (CV && !isa<GlobalValue>(CV)) {
assert(TypePrinter && "Constants require TypePrinting!");
- WriteConstantInt(Out, CV, *TypePrinter, Machine);
+ WriteConstantInternal(Out, CV, *TypePrinter, Machine, Context);
return;
}
if (const MDNode *N = dyn_cast<MDNode>(V)) {
if (N->isFunctionLocal()) {
// Print metadata inline, not via slot reference number.
- WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine);
+ WriteMDNodeBodyInternal(Out, N, TypePrinter, Machine, Context);
return;
}
-
- if (!Machine)
- Machine = createSlotTracker(V);
- Out << '!' << Machine->getMetadataSlot(N);
+
+ if (!Machine) {
+ if (N->isFunctionLocal())
+ Machine = new SlotTracker(N->getFunction());
+ else
+ Machine = new SlotTracker(Context);
+ }
+ int Slot = Machine->getMetadataSlot(N);
+ if (Slot == -1)
+ Out << "<badref>";
+ else
+ Out << '!' << Slot;
return;
}
char Prefix = '%';
int Slot;
+ // If we have a SlotTracker, use it.
if (Machine) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
Slot = Machine->getGlobalSlot(GV);
Prefix = '@';
} else {
Slot = Machine->getLocalSlot(V);
+
+ // If the local value didn't succeed, then we may be referring to a value
+ // from a different function. Translate it, as this can happen when using
+ // address of blocks.
+ if (Slot == -1)
+ if ((Machine = createSlotTracker(V))) {
+ Slot = Machine->getLocalSlot(V);
+ delete Machine;
+ }
}
- } else {
- Machine = createSlotTracker(V);
- if (Machine) {
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
- Slot = Machine->getGlobalSlot(GV);
- Prefix = '@';
- } else {
- Slot = Machine->getLocalSlot(V);
- }
- delete Machine;
+ } else if ((Machine = createSlotTracker(V))) {
+ // Otherwise, create one to get the # and then destroy it.
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ Slot = Machine->getGlobalSlot(GV);
+ Prefix = '@';
} else {
- Slot = -1;
+ Slot = Machine->getLocalSlot(V);
}
+ delete Machine;
+ Machine = 0;
+ } else {
+ Slot = -1;
}
if (Slot != -1)
// Fast path: Don't construct and populate a TypePrinting object if we
// won't be needing any types printed.
if (!PrintType &&
- (!isa<Constant>(V) || V->hasName() || isa<GlobalValue>(V))) {
- WriteAsOperandInternal(Out, V, 0, 0);
+ ((!isa<Constant>(V) && !isa<MDNode>(V)) ||
+ V->hasName() || isa<GlobalValue>(V))) {
+ WriteAsOperandInternal(Out, V, 0, 0, Context);
return;
}
if (Context == 0) Context = getModuleFromVal(V);
TypePrinting TypePrinter;
- std::vector<const Type*> NumberedTypes;
- AddModuleTypesToPrinter(TypePrinter, NumberedTypes, Context);
+ if (Context)
+ TypePrinter.incorporateTypes(*Context);
if (PrintType) {
TypePrinter.print(V->getType(), Out);
Out << ' ';
}
- WriteAsOperandInternal(Out, V, &TypePrinter, 0);
+ WriteAsOperandInternal(Out, V, &TypePrinter, 0, Context);
}
namespace {
const Module *TheModule;
TypePrinting TypePrinter;
AssemblyAnnotationWriter *AnnotationWriter;
- std::vector<const Type*> NumberedTypes;
-
+
public:
inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
const Module *M,
AssemblyAnnotationWriter *AAW)
: Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) {
- AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M);
+ if (M)
+ TypePrinter.incorporateTypes(*M);
}
void printMDNodeBody(const MDNode *MD);
void printNamedMDNode(const NamedMDNode *NMD);
-
+
void printModule(const Module *M);
void writeOperand(const Value *Op, bool PrintType);
void writeParamOperand(const Value *Operand, Attributes Attrs);
+ void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope);
void writeAllMDNodes();
- void printTypeSymbolTable(const TypeSymbolTable &ST);
+ void printTypeIdentities();
void printGlobal(const GlobalVariable *GV);
void printAlias(const GlobalAlias *GV);
void printFunction(const Function *F);
TypePrinter.print(Operand->getType(), Out);
Out << ' ';
}
- WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine);
+ WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
+}
+
+void AssemblyWriter::writeAtomic(AtomicOrdering Ordering,
+ SynchronizationScope SynchScope) {
+ if (Ordering == NotAtomic)
+ return;
+
+ switch (SynchScope) {
+ default: Out << " <bad scope " << int(SynchScope) << ">"; break;
+ case SingleThread: Out << " singlethread"; break;
+ case CrossThread: break;
+ }
+
+ switch (Ordering) {
+ default: Out << " <bad ordering " << int(Ordering) << ">"; break;
+ case Unordered: Out << " unordered"; break;
+ case Monotonic: Out << " monotonic"; break;
+ case Acquire: Out << " acquire"; break;
+ case Release: Out << " release"; break;
+ case AcquireRelease: Out << " acq_rel"; break;
+ case SequentiallyConsistent: Out << " seq_cst"; break;
+ }
}
void AssemblyWriter::writeParamOperand(const Value *Operand,
Out << ' ' << Attribute::getAsString(Attrs);
Out << ' ';
// Print the operand
- WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine);
+ WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
}
void AssemblyWriter::printModule(const Module *M) {
CurPos = NewLine+1;
NewLine = Asm.find_first_of('\n', CurPos);
}
- Out << "module asm \"";
- PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out);
- Out << "\"\n";
+ std::string rest(Asm.begin()+CurPos, Asm.end());
+ if (!rest.empty()) {
+ Out << "module asm \"";
+ PrintEscapedString(rest, Out);
+ Out << "\"\n";
+ }
}
// Loop over the dependent libraries and emit them.
Out << " ]";
}
- // Loop over the symbol table, emitting all id'd types.
- if (!M->getTypeSymbolTable().empty() || !NumberedTypes.empty()) Out << '\n';
- printTypeSymbolTable(M->getTypeSymbolTable());
+ printTypeIdentities();
// Output all globals.
if (!M->global_empty()) Out << '\n';
// Output named metadata.
if (!M->named_metadata_empty()) Out << '\n';
-
+
for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
E = M->named_metadata_end(); I != E; ++I)
printNamedMDNode(I);
}
void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
- Out << "!" << NMD->getName() << " = !{";
+ Out << '!';
+ StringRef Name = NMD->getName();
+ if (Name.empty()) {
+ Out << "<empty name> ";
+ } else {
+ if (isalpha(Name[0]) || Name[0] == '-' || Name[0] == '$' ||
+ Name[0] == '.' || Name[0] == '_')
+ Out << Name[0];
+ else
+ Out << '\\' << hexdigit(Name[0] >> 4) << hexdigit(Name[0] & 0x0F);
+ for (unsigned i = 1, e = Name.size(); i != e; ++i) {
+ unsigned char C = Name[i];
+ if (isalnum(C) || C == '-' || C == '$' || C == '.' || C == '_')
+ Out << C;
+ else
+ Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
+ }
+ }
+ Out << " = !{";
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
if (i) Out << ", ";
- if (MDNode *MD = NMD->getOperand(i))
- Out << '!' << Machine.getMetadataSlot(MD);
+ int Slot = Machine.getMetadataSlot(NMD->getOperand(i));
+ if (Slot == -1)
+ Out << "<badref>";
else
- Out << "null";
+ Out << '!' << Slot;
}
Out << "}\n";
}
case GlobalValue::ExternalLinkage: break;
case GlobalValue::PrivateLinkage: Out << "private "; break;
case GlobalValue::LinkerPrivateLinkage: Out << "linker_private "; break;
+ case GlobalValue::LinkerPrivateWeakLinkage:
+ Out << "linker_private_weak ";
+ break;
+ case GlobalValue::LinkerPrivateWeakDefAutoLinkage:
+ Out << "linker_private_weak_def_auto ";
+ break;
case GlobalValue::InternalLinkage: Out << "internal "; break;
case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break;
case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break;
if (GV->isMaterializable())
Out << "; Materializable\n";
- WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine);
+ WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine, GV->getParent());
Out << " = ";
if (!GV->hasInitializer() && GV->hasExternalLinkage())
if (GV->isThreadLocal()) Out << "thread_local ";
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
Out << "addrspace(" << AddressSpace << ") ";
+ if (GV->hasUnnamedAddr()) Out << "unnamed_addr ";
Out << (GV->isConstant() ? "constant " : "global ");
TypePrinter.print(GV->getType()->getElementType(), Out);
writeOperand(GV->getInitializer(), false);
}
- if (GV->hasSection())
- Out << ", section \"" << GV->getSection() << '"';
+ if (GV->hasSection()) {
+ Out << ", section \"";
+ PrintEscapedString(GV->getSection(), Out);
+ Out << '"';
+ }
if (GV->getAlignment())
Out << ", align " << GV->getAlignment();
const Constant *Aliasee = GA->getAliasee();
- if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
- TypePrinter.print(GV->getType(), Out);
- Out << ' ';
- PrintLLVMName(Out, GV);
- } else if (const Function *F = dyn_cast<Function>(Aliasee)) {
- TypePrinter.print(F->getFunctionType(), Out);
- Out << "* ";
-
- WriteAsOperandInternal(Out, F, &TypePrinter, &Machine);
- } else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Aliasee)) {
+ if (Aliasee == 0) {
TypePrinter.print(GA->getType(), Out);
- Out << ' ';
- PrintLLVMName(Out, GA);
+ Out << " <<NULL ALIASEE>>";
} else {
- const ConstantExpr *CE = cast<ConstantExpr>(Aliasee);
- // The only valid GEP is an all zero GEP.
- assert((CE->getOpcode() == Instruction::BitCast ||
- CE->getOpcode() == Instruction::GetElementPtr) &&
- "Unsupported aliasee");
- writeOperand(CE, false);
+ writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
}
printInfoComment(*GA);
Out << '\n';
}
-void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
+void AssemblyWriter::printTypeIdentities() {
+ if (TypePrinter.NumberedTypes.empty() &&
+ TypePrinter.NamedTypes.empty())
+ return;
+
+ Out << '\n';
+
+ // We know all the numbers that each type is used and we know that it is a
+ // dense assignment. Convert the map to an index table.
+ std::vector<StructType*> NumberedTypes(TypePrinter.NumberedTypes.size());
+ for (DenseMap<StructType*, unsigned>::iterator I =
+ TypePrinter.NumberedTypes.begin(), E = TypePrinter.NumberedTypes.end();
+ I != E; ++I) {
+ assert(I->second < NumberedTypes.size() && "Didn't get a dense numbering?");
+ NumberedTypes[I->second] = I->first;
+ }
+
// Emit all numbered types.
for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) {
Out << '%' << i << " = type ";
// Make sure we print out at least one level of the type structure, so
// that we do not get %2 = type %2
- TypePrinter.printAtLeastOneLevel(NumberedTypes[i], Out);
+ TypePrinter.printStructBody(NumberedTypes[i], Out);
Out << '\n';
}
- // Print the named types.
- for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
- TI != TE; ++TI) {
- PrintLLVMName(Out, TI->first, LocalPrefix);
+ for (unsigned i = 0, e = TypePrinter.NamedTypes.size(); i != e; ++i) {
+ PrintLLVMName(Out, TypePrinter.NamedTypes[i]->getName(), LocalPrefix);
Out << " = type ";
// Make sure we print out at least one level of the type structure, so
// that we do not get %FILE = type %FILE
- TypePrinter.printAtLeastOneLevel(TI->second, Out);
+ TypePrinter.printStructBody(TypePrinter.NamedTypes[i], Out);
Out << '\n';
}
}
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_ThisCall: Out << "x86_thiscallcc "; break;
case CallingConv::ARM_APCS: Out << "arm_apcscc "; break;
case CallingConv::ARM_AAPCS: Out << "arm_aapcscc "; break;
case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break;
case CallingConv::MSP430_INTR: Out << "msp430_intrcc "; break;
+ case CallingConv::PTX_Kernel: Out << "ptx_kernel "; break;
+ case CallingConv::PTX_Device: Out << "ptx_device "; break;
default: Out << "cc" << F->getCallingConv() << " "; break;
}
- const FunctionType *FT = F->getFunctionType();
+ FunctionType *FT = F->getFunctionType();
const AttrListPtr &Attrs = F->getAttributes();
Attributes RetAttrs = Attrs.getRetAttributes();
if (RetAttrs != Attribute::None)
Out << Attribute::getAsString(Attrs.getRetAttributes()) << ' ';
TypePrinter.print(F->getReturnType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, F, &TypePrinter, &Machine);
+ WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
Out << '(';
Machine.incorporateFunction(F);
Out << "..."; // Output varargs portion of signature!
}
Out << ')';
+ if (F->hasUnnamedAddr())
+ Out << " unnamed_addr";
Attributes FnAttrs = Attrs.getFnAttributes();
if (FnAttrs != Attribute::None)
Out << ' ' << Attribute::getAsString(Attrs.getFnAttributes());
- if (F->hasSection())
- Out << " section \"" << F->getSection() << '"';
+ if (F->hasSection()) {
+ Out << " section \"";
+ PrintEscapedString(F->getSection(), Out);
+ Out << '"';
+ }
if (F->getAlignment())
Out << " align " << F->getAlignment();
if (F->hasGC())
Out << " gc \"" << F->getGC() << '"';
if (F->isDeclaration()) {
- Out << "\n";
+ Out << '\n';
} else {
Out << " {";
-
- // Output all of its basic blocks... for the function
+ // Output all of the function's basic blocks.
for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I)
printBasicBlock(I);
Out.PadToColumn(50);
Out << "; Error: Block without parent!";
} else if (BB != &BB->getParent()->getEntryBlock()) { // Not the entry block?
- // Output predecessors for the block...
+ // Output predecessors for the block.
Out.PadToColumn(50);
Out << ";";
- pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB);
+ const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
if (PI == PE) {
Out << " No predecessors!";
AnnotationWriter->printInfoComment(V, Out);
return;
}
-
- if (V.getType()->isVoidTy()) return;
-
- Out.PadToColumn(50);
- Out << "; <";
- TypePrinter.print(V.getType(), Out);
- Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses
}
// This member is called for each Instruction in a function..
Out << '%' << SlotNum << " = ";
}
- // If this is a volatile load or store, print out the volatile marker.
- if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
- (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile())) {
- Out << "volatile ";
- } else if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall()) {
- // If this is a call, check if it's a tail call.
+ if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall())
Out << "tail ";
- }
// Print out the opcode...
Out << I.getOpcodeName();
+ // If this is an atomic load or store, print out the atomic marker.
+ if ((isa<LoadInst>(I) && cast<LoadInst>(I).isAtomic()) ||
+ (isa<StoreInst>(I) && cast<StoreInst>(I).isAtomic()))
+ Out << " atomic";
+
+ // If this is a volatile operation, print out the volatile marker.
+ if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
+ (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) ||
+ (isa<AtomicCmpXchgInst>(I) && cast<AtomicCmpXchgInst>(I).isVolatile()) ||
+ (isa<AtomicRMWInst>(I) && cast<AtomicRMWInst>(I).isVolatile()))
+ Out << " volatile";
+
// Print out optimization information.
WriteOptimizationInfo(Out, &I);
if (const CmpInst *CI = dyn_cast<CmpInst>(&I))
Out << ' ' << getPredicateText(CI->getPredicate());
+ // Print out the atomicrmw operation
+ if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I))
+ writeAtomicRMWOperation(Out, RMWI->getOperation());
+
// Print out the type of the operands...
const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0;
writeOperand(BI.getSuccessor(1), true);
} else if (isa<SwitchInst>(I)) {
+ SwitchInst& SI(cast<SwitchInst>(I));
// Special case switch instruction to get formatting nice and correct.
Out << ' ';
- writeOperand(Operand , true);
+ writeOperand(SI.getCondition(), true);
Out << ", ";
- writeOperand(I.getOperand(1), true);
+ writeOperand(SI.getDefaultDest(), true);
Out << " [";
-
- for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) {
+ // Skip the first item since that's the default case.
+ unsigned NumCases = SI.getNumCases();
+ for (unsigned i = 1; i < NumCases; ++i) {
Out << "\n ";
- writeOperand(I.getOperand(op ), true);
+ writeOperand(SI.getCaseValue(i), true);
Out << ", ";
- writeOperand(I.getOperand(op+1), true);
+ writeOperand(SI.getSuccessor(i), true);
}
Out << "\n ]";
} else if (isa<IndirectBrInst>(I)) {
Out << ' ';
writeOperand(Operand, true);
Out << ", [";
-
+
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
if (i != 1)
Out << ", ";
writeOperand(I.getOperand(i), true);
}
Out << ']';
- } else if (isa<PHINode>(I)) {
+ } else if (const PHINode *PN = dyn_cast<PHINode>(&I)) {
Out << ' ';
TypePrinter.print(I.getType(), Out);
Out << ' ';
- for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
+ for (unsigned op = 0, Eop = PN->getNumIncomingValues(); op < Eop; ++op) {
if (op) Out << ", ";
Out << "[ ";
- writeOperand(I.getOperand(op ), false); Out << ", ";
- writeOperand(I.getOperand(op+1), false); Out << " ]";
+ writeOperand(PN->getIncomingValue(op), false); Out << ", ";
+ writeOperand(PN->getIncomingBlock(op), false); Out << " ]";
}
} else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(&I)) {
Out << ' ';
writeOperand(I.getOperand(1), true);
for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i)
Out << ", " << *i;
+ } else if (const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&I)) {
+ Out << ' ';
+ TypePrinter.print(I.getType(), Out);
+ Out << " personality ";
+ writeOperand(I.getOperand(0), true); Out << '\n';
+
+ if (LPI->isCleanup())
+ Out << " cleanup";
+
+ for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
+ if (i != 0 || LPI->isCleanup()) Out << "\n";
+ if (LPI->isCatch(i))
+ Out << " catch ";
+ else
+ Out << " filter ";
+
+ writeOperand(LPI->getClause(i), true);
+ }
} else if (isa<ReturnInst>(I) && !Operand) {
Out << " void";
} else if (const CallInst *CI = dyn_cast<CallInst>(&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_ThisCall: Out << " x86_thiscallcc"; break;
case CallingConv::ARM_APCS: Out << " arm_apcscc "; break;
case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break;
case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break;
+ case CallingConv::PTX_Kernel: Out << " ptx_kernel"; break;
+ case CallingConv::PTX_Device: Out << " ptx_device"; break;
default: Out << " cc" << CI->getCallingConv(); break;
}
- const PointerType *PTy = cast<PointerType>(Operand->getType());
- const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
- const Type *RetTy = FTy->getReturnType();
+ Operand = CI->getCalledValue();
+ PointerType *PTy = cast<PointerType>(Operand->getType());
+ FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+ Type *RetTy = FTy->getReturnType();
const AttrListPtr &PAL = CI->getAttributes();
if (PAL.getRetAttributes() != Attribute::None)
writeOperand(Operand, true);
}
Out << '(';
- for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) {
- if (op > 1)
+ for (unsigned op = 0, Eop = CI->getNumArgOperands(); op < Eop; ++op) {
+ if (op > 0)
Out << ", ";
- writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op));
+ writeParamOperand(CI->getArgOperand(op), PAL.getParamAttributes(op + 1));
}
Out << ')';
if (PAL.getFnAttributes() != Attribute::None)
Out << ' ' << Attribute::getAsString(PAL.getFnAttributes());
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
- const PointerType *PTy = cast<PointerType>(Operand->getType());
- const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
- const Type *RetTy = FTy->getReturnType();
+ Operand = II->getCalledValue();
+ PointerType *PTy = cast<PointerType>(Operand->getType());
+ FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+ Type *RetTy = FTy->getReturnType();
const AttrListPtr &PAL = II->getAttributes();
// Print the calling convention being used.
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_ThisCall: Out << " x86_thiscallcc"; break;
case CallingConv::ARM_APCS: Out << " arm_apcscc "; break;
case CallingConv::ARM_AAPCS: Out << " arm_aapcscc "; break;
case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
case CallingConv::MSP430_INTR: Out << " msp430_intrcc "; break;
+ case CallingConv::PTX_Kernel: Out << " ptx_kernel"; break;
+ case CallingConv::PTX_Device: Out << " ptx_device"; break;
default: Out << " cc" << II->getCallingConv(); break;
}
writeOperand(Operand, true);
}
Out << '(';
- for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) {
- if (op > 3)
+ for (unsigned op = 0, Eop = II->getNumArgOperands(); op < Eop; ++op) {
+ if (op)
Out << ", ";
- writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op-2));
+ writeParamOperand(II->getArgOperand(op), PAL.getParamAttributes(op + 1));
}
Out << ')';
// omit the type from all but the first operand. If the instruction has
// different type operands (for example br), then they are all printed.
bool PrintAllTypes = false;
- const Type *TheType = Operand->getType();
+ Type *TheType = Operand->getType();
// Select, Store and ShuffleVector always print all types.
if (isa<SelectInst>(I) || isa<StoreInst>(I) || isa<ShuffleVectorInst>(I)
}
}
- // Print post operand alignment for load/store.
- if (isa<LoadInst>(I) && cast<LoadInst>(I).getAlignment()) {
- Out << ", align " << cast<LoadInst>(I).getAlignment();
- } else if (isa<StoreInst>(I) && cast<StoreInst>(I).getAlignment()) {
- Out << ", align " << cast<StoreInst>(I).getAlignment();
+ // Print atomic ordering/alignment for memory operations
+ if (const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
+ if (LI->isAtomic())
+ writeAtomic(LI->getOrdering(), LI->getSynchScope());
+ if (LI->getAlignment())
+ Out << ", align " << LI->getAlignment();
+ } else if (const StoreInst *SI = dyn_cast<StoreInst>(&I)) {
+ if (SI->isAtomic())
+ writeAtomic(SI->getOrdering(), SI->getSynchScope());
+ if (SI->getAlignment())
+ Out << ", align " << SI->getAlignment();
+ } else if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(&I)) {
+ writeAtomic(CXI->getOrdering(), CXI->getSynchScope());
+ } else if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I)) {
+ writeAtomic(RMWI->getOrdering(), RMWI->getSynchScope());
+ } else if (const FenceInst *FI = dyn_cast<FenceInst>(&I)) {
+ writeAtomic(FI->getOrdering(), FI->getSynchScope());
}
// Print Metadata info.
} else {
Out << ", !<unknown kind #" << Kind << ">";
}
- Out << " !" << Machine.getMetadataSlot(InstMD[i].second);
+ Out << ' ';
+ WriteAsOperandInternal(Out, InstMD[i].second, &TypePrinter, &Machine,
+ TheModule);
}
}
printInfoComment(I);
}
static void WriteMDNodeComment(const MDNode *Node,
- formatted_raw_ostream &Out) {
+ formatted_raw_ostream &Out) {
if (Node->getNumOperands() < 1)
return;
ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Node->getOperand(0));
if (!CI) return;
- unsigned Val = CI->getZExtValue();
- unsigned Tag = Val & ~LLVMDebugVersionMask;
- if (Val < LLVMDebugVersion)
+ APInt Val = CI->getValue();
+ APInt Tag = Val & ~APInt(Val.getBitWidth(), LLVMDebugVersionMask);
+ if (Val.ult(LLVMDebugVersion))
return;
-
+
Out.PadToColumn(50);
- if (Tag == dwarf::DW_TAG_auto_variable)
- Out << "; [ DW_TAG_auto_variable ]";
- else if (Tag == dwarf::DW_TAG_arg_variable)
- Out << "; [ DW_TAG_arg_variable ]";
- else if (Tag == dwarf::DW_TAG_return_variable)
- Out << "; [ DW_TAG_return_variable ]";
- else if (Tag == dwarf::DW_TAG_vector_type)
- Out << "; [ DW_TAG_vector_type ]";
- else if (Tag == dwarf::DW_TAG_user_base)
+ if (Tag == dwarf::DW_TAG_user_base)
Out << "; [ DW_TAG_user_base ]";
- else if (const char *TagName = dwarf::TagString(Tag))
- Out << "; [ " << TagName << " ]";
+ else if (Tag.isIntN(32)) {
+ if (const char *TagName = dwarf::TagString(Tag.getZExtValue()))
+ Out << "; [ " << TagName << " ]";
+ }
}
void AssemblyWriter::writeAllMDNodes() {
for (SlotTracker::mdn_iterator I = Machine.mdn_begin(), E = Machine.mdn_end();
I != E; ++I)
Nodes[I->second] = cast<MDNode>(I->first);
-
+
for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
Out << '!' << i << " = metadata ";
printMDNodeBody(Nodes[i]);
}
void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
- WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine);
+ WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule);
WriteMDNodeComment(Node, Out);
Out << "\n";
}
W.printModule(this);
}
+void NamedMDNode::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
+ SlotTracker SlotTable(getParent());
+ formatted_raw_ostream OS(ROS);
+ AssemblyWriter W(OS, SlotTable, getParent(), AAW);
+ W.printNamedMDNode(this);
+}
+
void Type::print(raw_ostream &OS) const {
if (this == 0) {
OS << "<null Type>";
return;
}
- TypePrinting().print(this, OS);
+ TypePrinting TP;
+ TP.print(const_cast<Type*>(this), OS);
+
+ // If the type is a named struct type, print the body as well.
+ if (StructType *STy = dyn_cast<StructType>(const_cast<Type*>(this)))
+ if (!STy->isLiteral()) {
+ OS << " = type ";
+ TP.printStructBody(STy, OS);
+ }
}
void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
} else if (const MDNode *N = dyn_cast<MDNode>(this)) {
const Function *F = N->getFunction();
SlotTracker SlotTable(F);
- AssemblyWriter W(OS, SlotTable, F ? getModuleFromVal(F) : 0, AAW);
+ AssemblyWriter W(OS, SlotTable, F ? F->getParent() : 0, AAW);
W.printMDNodeBody(N);
- } else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(this)) {
- SlotTracker SlotTable(N->getParent());
- AssemblyWriter W(OS, SlotTable, N->getParent(), AAW);
- W.printNamedMDNode(N);
} else if (const Constant *C = dyn_cast<Constant>(this)) {
TypePrinting TypePrinter;
TypePrinter.print(C->getType(), OS);
OS << ' ';
- WriteConstantInt(OS, C, TypePrinter, 0);
+ WriteConstantInternal(OS, C, TypePrinter, 0, 0);
} else if (isa<InlineAsm>(this) || isa<MDString>(this) ||
isa<Argument>(this)) {
WriteAsOperand(OS, this, true, 0);
void Value::dump() const { print(dbgs()); dbgs() << '\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(dbgs(), this, Context);
- dbgs() << '\n';
-}
-
-// Type::dump - allow easy printing of Types from the debugger.
-void Type::dump() const { dump(0); }
+void Type::dump() const { print(dbgs()); }
// Module::dump() - Allow printing of Modules from the debugger.
void Module::dump() const { print(dbgs(), 0); }