aboutsummaryrefslogtreecommitdiff
path: root/lib/IR
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2013-01-02 09:10:48 +0000
committerChandler Carruth <chandlerc@gmail.com>2013-01-02 09:10:48 +0000
commitc2c50cdcdc19a1bca993c06d13d8cdca87083ce4 (patch)
treee46b4b6d4d44228df1e870f690506dbf296954c1 /lib/IR
parent3af932322859285988a4c53551540fc0658b2116 (diff)
Rename VMCore directory to IR.
Aside from moving the actual files, this patch only updates the build system and the source file comments under lib/... that are relevant. I'll be updating other docs and other files in smaller subsequnet commits. While I've tried to test this, but it is entirely possible that there will still be some build system fallout. Also, note that I've not changed the library name itself: libLLVMCore.a is still the library name. I'd be interested in others' opinions about whether we should rename this as well (I think we should, just not sure what it might break) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171359 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r--lib/IR/AsmWriter.cpp2159
-rw-r--r--lib/IR/AttributeImpl.h113
-rw-r--r--lib/IR/Attributes.cpp602
-rw-r--r--lib/IR/AutoUpgrade.cpp393
-rw-r--r--lib/IR/BasicBlock.cpp371
-rw-r--r--lib/IR/CMakeLists.txt52
-rw-r--r--lib/IR/ConstantFold.cpp2066
-rw-r--r--lib/IR/ConstantFold.h56
-rw-r--r--lib/IR/Constants.cpp2769
-rw-r--r--lib/IR/ConstantsContext.h774
-rw-r--r--lib/IR/Core.cpp2408
-rw-r--r--lib/IR/DIBuilder.cpp1045
-rw-r--r--lib/IR/DataLayout.cpp725
-rw-r--r--lib/IR/DebugInfo.cpp1197
-rw-r--r--lib/IR/DebugLoc.cpp315
-rw-r--r--lib/IR/Dominators.cpp302
-rw-r--r--lib/IR/Function.cpp665
-rw-r--r--lib/IR/GCOV.cpp283
-rw-r--r--lib/IR/GVMaterializer.cpp18
-rw-r--r--lib/IR/Globals.cpp264
-rw-r--r--lib/IR/IRBuilder.cpp153
-rw-r--r--lib/IR/InlineAsm.cpp295
-rw-r--r--lib/IR/Instruction.cpp551
-rw-r--r--lib/IR/Instructions.cpp3540
-rw-r--r--lib/IR/IntrinsicInst.cpp73
-rw-r--r--lib/IR/LLVMBuild.txt22
-rw-r--r--lib/IR/LLVMContext.cpp187
-rw-r--r--lib/IR/LLVMContextImpl.cpp149
-rw-r--r--lib/IR/LLVMContextImpl.h361
-rw-r--r--lib/IR/LeakDetector.cpp69
-rw-r--r--lib/IR/LeaksContext.h92
-rw-r--r--lib/IR/Makefile33
-rw-r--r--lib/IR/Metadata.cpp744
-rw-r--r--lib/IR/Module.cpp451
-rw-r--r--lib/IR/Pass.cpp277
-rw-r--r--lib/IR/PassManager.cpp1917
-rw-r--r--lib/IR/PassRegistry.cpp209
-rw-r--r--lib/IR/PrintModulePass.cpp100
-rw-r--r--lib/IR/SymbolTableListTraitsImpl.h118
-rw-r--r--lib/IR/TargetTransformInfo.cpp31
-rw-r--r--lib/IR/Type.cpp767
-rw-r--r--lib/IR/TypeFinder.cpp148
-rw-r--r--lib/IR/Use.cpp145
-rw-r--r--lib/IR/User.cpp90
-rw-r--r--lib/IR/Value.cpp698
-rw-r--r--lib/IR/ValueSymbolTable.cpp117
-rw-r--r--lib/IR/ValueTypes.cpp277
-rw-r--r--lib/IR/Verifier.cpp2015
48 files changed, 30206 insertions, 0 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp
new file mode 100644
index 0000000000..7e80322cc6
--- /dev/null
+++ b/lib/IR/AsmWriter.cpp
@@ -0,0 +1,2159 @@
+//===-- AsmWriter.cpp - Printing LLVM as an assembly file -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This library implements the functionality defined in llvm/Assembly/Writer.h
+//
+// Note that these routines must be extremely tolerant of various errors in the
+// LLVM code, because it can be used for debugging transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Assembly/Writer.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Assembly/AssemblyAnnotationWriter.h"
+#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/CallingConv.h"
+#include "llvm/Constants.h"
+#include "llvm/DebugInfo.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Operator.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/TypeFinder.h"
+#include "llvm/ValueSymbolTable.h"
+#include <algorithm>
+#include <cctype>
+using namespace llvm;
+
+// Make virtual table appear in this compilation unit.
+AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {}
+
+//===----------------------------------------------------------------------===//
+// Helper Functions
+//===----------------------------------------------------------------------===//
+
+static const Module *getModuleFromVal(const Value *V) {
+ if (const Argument *MA = dyn_cast<Argument>(V))
+ return MA->getParent() ? MA->getParent()->getParent() : 0;
+
+ if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
+ return BB->getParent() ? BB->getParent()->getParent() : 0;
+
+ if (const Instruction *I = dyn_cast<Instruction>(V)) {
+ 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();
+ return 0;
+}
+
+static void PrintCallingConv(unsigned cc, raw_ostream &Out)
+{
+ switch (cc) {
+ 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_ThisCall: Out << "x86_thiscallcc"; break;
+ case CallingConv::Intel_OCL_BI: Out << "intel_ocl_bicc"; 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" << cc; break;
+ }
+}
+
+// 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(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 != '"')
+ Out << C;
+ else
+ Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F);
+ }
+}
+
+enum PrefixType {
+ GlobalPrefix,
+ LabelPrefix,
+ LocalPrefix,
+ NoPrefix
+};
+
+/// 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, StringRef Name, PrefixType Prefix) {
+ assert(!Name.empty() && "Cannot get empty name!");
+ switch (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 = isdigit(Name[0]);
+ if (!NeedsQuotes) {
+ for (unsigned i = 0, e = Name.size(); i != e; ++i) {
+ // By making this unsigned, the value passed in to isalnum will always be
+ // in the range 0-255. This is important when building with MSVC because
+ // its implementation will assert. This situation can arise when dealing
+ // with UTF-8 multibyte characters.
+ unsigned char C = Name[i];
+ if (!isalnum(C) && C != '-' && C != '.' && C != '_') {
+ NeedsQuotes = true;
+ break;
+ }
+ }
+ }
+
+ // If we didn't need any quotes, just write out the name in one blast.
+ if (!NeedsQuotes) {
+ OS << Name;
+ return;
+ }
+
+ // Okay, we need quotes. Output the quotes and escape any scary characters as
+ // needed.
+ OS << '"';
+ PrintEscapedString(Name, OS);
+ OS << '"';
+}
+
+/// 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 Value *V) {
+ PrintLLVMName(OS, V->getName(),
+ isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
+}
+
+//===----------------------------------------------------------------------===//
+// TypePrinting Class: Type printing machinery
+//===----------------------------------------------------------------------===//
+
+/// TypePrinting - Type printing machinery.
+namespace {
+class TypePrinting {
+ TypePrinting(const TypePrinting &) LLVM_DELETED_FUNCTION;
+ void operator=(const TypePrinting&) LLVM_DELETED_FUNCTION;
+public:
+
+ /// NamedTypes - The named types that are used by the current module.
+ TypeFinder NamedTypes;
+
+ /// NumberedTypes - The numbered types, along with their value.
+ DenseMap<StructType*, unsigned> NumberedTypes;
+
+
+ TypePrinting() {}
+ ~TypePrinting() {}
+
+ void incorporateTypes(const Module &M);
+
+ void print(Type *Ty, raw_ostream &OS);
+
+ void printStructBody(StructType *Ty, raw_ostream &OS);
+};
+} // end anonymous namespace.
+
+
+void TypePrinting::incorporateTypes(const Module &M) {
+ NamedTypes.run(M, false);
+
+ // 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;
+ }
+
+ 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::HalfTyID: OS << "half"; break;
+ case Type::FloatTyID: OS << "float"; break;
+ case Type::DoubleTyID: OS << "double"; break;
+ case Type::X86_FP80TyID: OS << "x86_fp80"; break;
+ case Type::FP128TyID: OS << "fp128"; 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();
+ return;
+
+ case Type::FunctionTyID: {
+ 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 << ", ";
+ print(*I, OS);
+ }
+ if (FTy->isVarArg()) {
+ if (FTy->getNumParams()) OS << ", ";
+ OS << "...";
+ }
+ OS << ')';
+ return;
+ }
+ case Type::StructTyID: {
+ 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 " << STy << '\"';
+ return;
+ }
+ case Type::PointerTyID: {
+ PointerType *PTy = cast<PointerType>(Ty);
+ print(PTy->getElementType(), OS);
+ if (unsigned AddressSpace = PTy->getAddressSpace())
+ OS << " addrspace(" << AddressSpace << ')';
+ OS << '*';
+ return;
+ }
+ case Type::ArrayTyID: {
+ ArrayType *ATy = cast<ArrayType>(Ty);
+ OS << '[' << ATy->getNumElements() << " x ";
+ print(ATy->getElementType(), OS);
+ OS << ']';
+ return;
+ }
+ case Type::VectorTyID: {
+ VectorType *PTy = cast<VectorType>(Ty);
+ OS << "<" << PTy->getNumElements() << " x ";
+ print(PTy->getElementType(), OS);
+ OS << '>';
+ return;
+ }
+ default:
+ OS << "<unrecognized-type>";
+ return;
+ }
+}
+
+void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
+ if (STy->isOpaque()) {
+ OS << "opaque";
+ return;
+ }
+
+ if (STy->isPacked())
+ OS << '<';
+
+ 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);
+ }
+
+ OS << " }";
+ }
+ if (STy->isPacked())
+ OS << '>';
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// SlotTracker Class: Enumerate slot numbers for unnamed values
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+/// This class provides computation of slot numbers for LLVM Assembly writing.
+///
+class SlotTracker {
+public:
+ /// ValueMap - A mapping of Values to slot numbers.
+ typedef DenseMap<const Value*, unsigned> ValueMap;
+
+private:
+ /// TheModule - The module for which we are holding slot numbers.
+ const Module* TheModule;
+
+ /// TheFunction - The function for which we are holding slot numbers.
+ const Function* TheFunction;
+ bool FunctionProcessed;
+
+ /// mMap - The slot map for the module level data.
+ ValueMap mMap;
+ unsigned mNext;
+
+ /// fMap - The slot map for the function level data.
+ ValueMap fMap;
+ unsigned fNext;
+
+ /// mdnMap - Map for MDNodes.
+ DenseMap<const MDNode*, unsigned> mdnMap;
+ unsigned mdnNext;
+public:
+ /// Construct from a module
+ explicit SlotTracker(const Module *M);
+ /// Construct from a function, starting out in incorp state.
+ explicit SlotTracker(const Function *F);
+
+ /// Return the slot number of the specified value in it's type
+ /// plane. If something is not in the SlotTracker, return -1.
+ int getLocalSlot(const Value *V);
+ int getGlobalSlot(const GlobalValue *V);
+ int getMetadataSlot(const MDNode *N);
+
+ /// If you'd like to deal with a function instead of just a module, use
+ /// this method to get its data into the SlotTracker.
+ void incorporateFunction(const Function *F) {
+ TheFunction = F;
+ FunctionProcessed = false;
+ }
+
+ /// After calling incorporateFunction, use this method to remove the
+ /// most recently incorporated function from the SlotTracker. This
+ /// will reset the state of the machine back to just the module contents.
+ void purgeFunction();
+
+ /// MDNode map iterators.
+ typedef DenseMap<const MDNode*, unsigned>::iterator mdn_iterator;
+ mdn_iterator mdn_begin() { return mdnMap.begin(); }
+ mdn_iterator mdn_end() { return mdnMap.end(); }
+ unsigned mdn_size() const { return mdnMap.size(); }
+ bool mdn_empty() const { return mdnMap.empty(); }
+
+ /// This function does the actual initialization.
+ inline void initialize();
+
+ // Implementation Details
+private:
+ /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
+ void CreateModuleSlot(const GlobalValue *V);
+
+ /// CreateMetadataSlot - Insert the specified MDNode* into the slot table.
+ void CreateMetadataSlot(const MDNode *N);
+
+ /// CreateFunctionSlot - Insert the specified Value* into the slot table.
+ void CreateFunctionSlot(const Value *V);
+
+ /// Add all of the module level global variables (and their initializers)
+ /// and function declarations, but not the contents of those functions.
+ void processModule();
+
+ /// Add all of the functions arguments, basic blocks, and instructions.
+ void processFunction();
+
+ SlotTracker(const SlotTracker &) LLVM_DELETED_FUNCTION;
+ void operator=(const SlotTracker &) LLVM_DELETED_FUNCTION;
+};
+
+} // end anonymous namespace
+
+
+static SlotTracker *createSlotTracker(const Value *V) {
+ if (const Argument *FA = dyn_cast<Argument>(V))
+ return new SlotTracker(FA->getParent());
+
+ if (const Instruction *I = dyn_cast<Instruction>(V))
+ if (I->getParent())
+ return new SlotTracker(I->getParent()->getParent());
+
+ if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
+ return new SlotTracker(BB->getParent());
+
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+ return new SlotTracker(GV->getParent());
+
+ if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
+ return new SlotTracker(GA->getParent());
+
+ if (const Function *Func = dyn_cast<Function>(V))
+ return new SlotTracker(Func);
+
+ if (const MDNode *MD = dyn_cast<MDNode>(V)) {
+ if (!MD->isFunctionLocal())
+ return new SlotTracker(MD->getFunction());
+
+ return new SlotTracker((Function *)0);
+ }
+
+ return 0;
+}
+
+#if 0
+#define ST_DEBUG(X) dbgs() << X
+#else
+#define ST_DEBUG(X)
+#endif
+
+// 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),
+ mNext(0), fNext(0), mdnNext(0) {
+}
+
+// Function level constructor. Causes the contents of the Module and the one
+// function provided to be added to the slot table.
+SlotTracker::SlotTracker(const Function *F)
+ : TheModule(F ? F->getParent() : 0), TheFunction(F), FunctionProcessed(false),
+ mNext(0), fNext(0), mdnNext(0) {
+}
+
+inline void SlotTracker::initialize() {
+ if (TheModule) {
+ processModule();
+ TheModule = 0; ///< Prevent re-processing next time we're called.
+ }
+
+ if (TheFunction && !FunctionProcessed)
+ processFunction();
+}
+
+// Iterate through all the global variables, functions, and global
+// variable initializers and create slots for them.
+void SlotTracker::processModule() {
+ ST_DEBUG("begin processModule!\n");
+
+ // Add all of the unnamed global variables to the value table.
+ for (Module::const_global_iterator I = TheModule->global_begin(),
+ E = TheModule->global_end(); I != E; ++I) {
+ if (!I->hasName())
+ CreateModuleSlot(I);
+ }
+
+ // Add metadata used by named metadata.
+ for (Module::const_named_metadata_iterator
+ 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)
+ CreateMetadataSlot(NMD->getOperand(i));
+ }
+
+ // Add all the unnamed functions to the table.
+ for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
+ I != E; ++I)
+ if (!I->hasName())
+ CreateModuleSlot(I);
+
+ ST_DEBUG("end processModule!\n");
+}
+
+// Process the arguments, basic blocks, and instructions of a function.
+void SlotTracker::processFunction() {
+ ST_DEBUG("begin processFunction!\n");
+ fNext = 0;
+
+ // Add all the function arguments with no names.
+ for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
+ AE = TheFunction->arg_end(); AI != AE; ++AI)
+ if (!AI->hasName())
+ CreateFunctionSlot(AI);
+
+ ST_DEBUG("Inserting Instructions:\n");
+
+ SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
+
+ // Add all of the basic blocks and instructions with no names.
+ for (Function::const_iterator BB = TheFunction->begin(),
+ 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. 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);
+ for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
+ CreateMetadataSlot(MDForInst[i].second);
+ MDForInst.clear();
+ }
+ }
+
+ FunctionProcessed = true;
+
+ ST_DEBUG("end processFunction!\n");
+}
+
+/// Clean up after incorporating a function. This is the only way to get out of
+/// the function incorporation state that affects get*Slot/Create*Slot. Function
+/// incorporation state is indicated by TheFunction != 0.
+void SlotTracker::purgeFunction() {
+ ST_DEBUG("begin purgeFunction!\n");
+ fMap.clear(); // Simply discard the function level map
+ TheFunction = 0;
+ FunctionProcessed = false;
+ ST_DEBUG("end purgeFunction!\n");
+}
+
+/// getGlobalSlot - Get the slot number of a global value.
+int SlotTracker::getGlobalSlot(const GlobalValue *V) {
+ // Check for uninitialized state and do lazy initialization.
+ initialize();
+
+ // Find the value in the module map
+ ValueMap::iterator MI = mMap.find(V);
+ return MI == mMap.end() ? -1 : (int)MI->second;
+}
+
+/// getMetadataSlot - Get the slot number of a MDNode.
+int SlotTracker::getMetadataSlot(const MDNode *N) {
+ // Check for uninitialized state and do lazy initialization.
+ initialize();
+
+ // Find the MDNode in the module map
+ mdn_iterator MI = mdnMap.find(N);
+ return MI == mdnMap.end() ? -1 : (int)MI->second;
+}
+
+
+/// getLocalSlot - Get the slot number for a value that is local to a function.
+int SlotTracker::getLocalSlot(const Value *V) {
+ assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");
+
+ // Check for uninitialized state and do lazy initialization.
+ initialize();
+
+ ValueMap::iterator FI = fMap.find(V);
+ return FI == fMap.end() ? -1 : (int)FI->second;
+}
+
+
+/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
+void SlotTracker::CreateModuleSlot(const GlobalValue *V) {
+ assert(V && "Can't insert a null Value into SlotTracker!");
+ assert(!V->getType()->isVoidTy() && "Doesn't need a slot!");
+ assert(!V->hasName() && "Doesn't need a slot!");
+
+ unsigned DestSlot = mNext++;
+ mMap[V] = DestSlot;
+
+ ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
+ DestSlot << " [");
+ // G = Global, F = Function, A = Alias, o = other
+ ST_DEBUG((isa<GlobalVariable>(V) ? 'G' :
+ (isa<Function>(V) ? 'F' :
+ (isa<GlobalAlias>(V) ? 'A' : 'o'))) << "]\n");
+}
+
+/// CreateSlot - Create a new slot for the specified value if it has no name.
+void SlotTracker::CreateFunctionSlot(const Value *V) {
+ assert(!V->getType()->isVoidTy() && !V->hasName() && "Doesn't need a slot!");
+
+ unsigned DestSlot = fNext++;
+ fMap[V] = DestSlot;
+
+ // G = Global, F = Function, o = other
+ ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
+ DestSlot << " [o]\n");
+}
+
+/// CreateModuleSlot - Insert the specified MDNode* into the slot table.
+void SlotTracker::CreateMetadataSlot(const MDNode *N) {
+ assert(N && "Can't insert a null Value into SlotTracker!");
+
+ // Don't insert if N is a function-local metadata, these are always printed
+ // inline.
+ if (!N->isFunctionLocal()) {
+ mdn_iterator I = mdnMap.find(N);
+ if (I != mdnMap.end())
+ return;
+
+ unsigned DestSlot = mdnNext++;
+ mdnMap[N] = DestSlot;
+ }
+
+ // Recursively add any MDNodes referenced by operands.
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+ if (const MDNode *Op = dyn_cast_or_null<MDNode>(N->getOperand(i)))
+ CreateMetadataSlot(Op);
+}
+
+//===----------------------------------------------------------------------===//
+// AsmWriter Implementation
+//===----------------------------------------------------------------------===//
+
+static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
+ TypePrinting *TypePrinter,
+ SlotTracker *Machine,
+ const Module *Context);
+
+
+
+static const char *getPredicateText(unsigned predicate) {
+ const char * pred = "unknown";
+ switch (predicate) {
+ case FCmpInst::FCMP_FALSE: pred = "false"; break;
+ case FCmpInst::FCMP_OEQ: pred = "oeq"; break