From 0d1b77e2824115d97f8392c3f4ec257b27ebbd7a Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Wed, 26 May 2004 07:18:52 +0000 Subject: [PATCH] Part of bug 122. Removed dependency of AsmWriter on SlotCalculator by incorporating a significantly simpler "SlotMachine" into this file. The SlotMachine is tailored for use by only the AsmWriter whose requirements for slot numbers are vastly different than from the Bytecode/Writer. Code change passes all Feature and Regression tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13784 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/VMCore/AsmWriter.cpp | 478 ++++++++++++++++++++++++++++++++++----- 1 file changed, 426 insertions(+), 52 deletions(-) diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 698e72539a7..9a791b43171 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -27,7 +27,6 @@ #include "llvm/iOther.h" #include "llvm/Module.h" #include "llvm/SymbolTable.h" -#include "llvm/Analysis/SlotCalculator.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "Support/StringExtras.h" @@ -35,6 +34,105 @@ #include using namespace llvm; +namespace { + +/// This class provides computation of slot numbers for LLVM Assembly writing. +/// @brief LLVM Assembly Writing Slot Computation. +class SlotMachine { + +/// @name Types +/// @{ +public: + + /// @brief A mapping of Values to slot numbers + typedef std::map ValueMap; + + /// @brief A plane with next slot number and ValueMap + struct Plane { + unsigned next_slot; ///< The next slot number to use + ValueMap map; ///< The map of Value* -> unsigned + Plane() { next_slot = 0; } ///< Make sure we start at 0 + }; + + /// @brief The map of planes by Type + typedef std::map TypedPlanes; + +/// @} +/// @name Constructors +/// @{ +public: + /// @brief Construct from a module + SlotMachine(const Module *M ); + + /// @brief Construct from a function, starting out in incorp state. + SlotMachine(const Function *F ); + +/// @} +/// @name Accessors +/// @{ +public: + /// Return the slot number of the specified value in it's type + /// plane. Its an error to ask for something not in the SlotMachine. + /// Its an error to ask for a Type* + unsigned getSlot(const Value *V) const; + +/// @} +/// @name Mutators +/// @{ +public: + /// If you'd like to deal with a function instead of just a module, use + /// this method to get its data into the SlotMachine. + void incorporateFunction(const Function *F); + + /// After calling incorporateFunction, use this method to remove the + /// most recently incorporated function from the SlotMachine. This + /// will reset the state of the machine back to just the module contents. + void purgeFunction(); + +/// @} +/// @name Implementation Details +/// @{ +private: + /// Values can be crammed into here at will. If they haven't + /// been inserted already, they get inserted, otherwise they are ignored. + /// Either way, the slot number for the Value* is returned. + unsigned createSlot(const Value *V); + + /// Insert a value into the value table. Return the slot number + /// that it now occupies. BadThings(TM) will happen if you insert a + /// Value that's already been inserted. + unsigned insertValue( 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(); + + SlotMachine(const SlotMachine &); // DO NOT IMPLEMENT + void operator=(const SlotMachine &); // DO NOT IMPLEMENT + +/// @} +/// @name Data +/// @{ +public: + + /// @brief The module for which we are holding slot numbers + const Module *TheModule; + + /// @brief Whether or not we have a function incorporated + bool FunctionIncorporated; + + /// @brief The TypePlanes map for the module level data + TypedPlanes mMap; + + /// @brief The TypePlanes map for the function level data + TypedPlanes fMap; + +/// @} + +}; + +} + static RegisterPass X("printm", "Print module to stderr",PassInfo::Analysis|PassInfo::Optimization); static RegisterPass @@ -43,7 +141,7 @@ Y("print","Print function to stderr",PassInfo::Analysis|PassInfo::Optimization); static void WriteAsOperandInternal(std::ostream &Out, const Value *V, bool PrintName, std::map &TypeTable, - SlotCalculator *Table); + SlotMachine *Machine); static const Module *getModuleFromVal(const Value *V) { if (const Argument *MA = dyn_cast(V)) @@ -58,18 +156,18 @@ static const Module *getModuleFromVal(const Value *V) { return 0; } -static SlotCalculator *createSlotCalculator(const Value *V) { +static SlotMachine *createSlotMachine(const Value *V) { assert(!isa(V) && "Can't create an SC for a type!"); if (const Argument *FA = dyn_cast(V)) { - return new SlotCalculator(FA->getParent(), false); + return new SlotMachine(FA->getParent()); } else if (const Instruction *I = dyn_cast(V)) { - return new SlotCalculator(I->getParent()->getParent(), false); + return new SlotMachine(I->getParent()->getParent()); } else if (const BasicBlock *BB = dyn_cast(V)) { - return new SlotCalculator(BB->getParent(), false); + return new SlotMachine(BB->getParent()); } else if (const GlobalVariable *GV = dyn_cast(V)){ - return new SlotCalculator(GV->getParent(), false); + return new SlotMachine(GV->getParent()); } else if (const Function *Func = dyn_cast(V)) { - return new SlotCalculator(Func, false); + return new SlotMachine(Func); } return 0; } @@ -246,7 +344,7 @@ std::ostream &llvm::WriteTypeSymbolic(std::ostream &Out, const Type *Ty, static void WriteConstantInt(std::ostream &Out, const Constant *CV, bool PrintName, std::map &TypeTable, - SlotCalculator *Table) { + SlotMachine *Machine) { if (const ConstantBool *CB = dyn_cast(CV)) { Out << (CB == ConstantBool::True ? "true" : "false"); } else if (const ConstantSInt *CI = dyn_cast(CV)) { @@ -322,12 +420,12 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, Out << " "; printTypeInt(Out, ETy, TypeTable); WriteAsOperandInternal(Out, CA->getOperand(0), - PrintName, TypeTable, Table); + PrintName, TypeTable, Machine); for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { Out << ", "; printTypeInt(Out, ETy, TypeTable); WriteAsOperandInternal(Out, CA->getOperand(i), PrintName, - TypeTable, Table); + TypeTable, Machine); } } Out << " ]"; @@ -339,14 +437,14 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable); WriteAsOperandInternal(Out, CS->getOperand(0), - PrintName, TypeTable, Table); + PrintName, TypeTable, Machine); for (unsigned i = 1; i < CS->getNumOperands(); i++) { Out << ", "; printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable); WriteAsOperandInternal(Out, CS->getOperand(i), - PrintName, TypeTable, Table); + PrintName, TypeTable, Machine); } } @@ -355,14 +453,14 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, Out << "null"; } else if (const ConstantPointerRef *PR = dyn_cast(CV)) { - WriteAsOperandInternal(Out, PR->getValue(), true, TypeTable, Table); + WriteAsOperandInternal(Out, PR->getValue(), true, TypeTable, Machine); } else if (const ConstantExpr *CE = dyn_cast(CV)) { Out << CE->getOpcodeName() << " ("; for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) { printTypeInt(Out, (*OI)->getType(), TypeTable); - WriteAsOperandInternal(Out, *OI, PrintName, TypeTable, Table); + WriteAsOperandInternal(Out, *OI, PrintName, TypeTable, Machine); if (OI+1 != CE->op_end()) Out << ", "; } @@ -386,35 +484,30 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, static void WriteAsOperandInternal(std::ostream &Out, const Value *V, bool PrintName, std::map &TypeTable, - SlotCalculator *Table) { + SlotMachine *Machine) { Out << " "; if (PrintName && V->hasName()) { Out << getLLVMName(V->getName()); } else { if (const Constant *CV = dyn_cast(V)) { - WriteConstantInt(Out, CV, PrintName, TypeTable, Table); + WriteConstantInt(Out, CV, PrintName, TypeTable, Machine); } else { int Slot; - if (Table) { - Slot = Table->getSlot(V); + if (Machine) { + Slot = Machine->getSlot(V); } else { if (const Type *Ty = dyn_cast(V)) { Out << Ty->getDescription(); return; } - Table = createSlotCalculator(V); - if (Table == 0) { Out << "BAD VALUE TYPE!"; return; } + Machine = createSlotMachine(V); + if (Machine == 0) { Out << "BAD VALUE TYPE!"; return; } - Slot = Table->getSlot(V); - delete Table; + Slot = Machine->getSlot(V); + delete Machine; } - if (Slot >= 0) Out << "%" << Slot; - else if (PrintName) - if (V->hasName()) - Out << "getName()) << ">"; - else - Out << ""; // Not embedded into a location? + Out << "%" << Slot; } } } @@ -447,14 +540,14 @@ namespace llvm { class AssemblyWriter { std::ostream *Out; - SlotCalculator &Table; + SlotMachine &Machine; const Module *TheModule; std::map TypeNames; AssemblyAnnotationWriter *AnnotationWriter; public: - inline AssemblyWriter(std::ostream &o, SlotCalculator &Tab, const Module *M, + inline AssemblyWriter(std::ostream &o, SlotMachine &Mac, const Module *M, AssemblyAnnotationWriter *AAW) - : Out(&o), Table(Tab), TheModule(M), AnnotationWriter(AAW) { + : Out(&o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { // If the module has a symbol table, take all global types and stuff their // names into the TypeNames map. @@ -548,7 +641,7 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) { void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, bool PrintName) { if (PrintType) { *Out << " "; printType(Operand->getType()); } - WriteAsOperandInternal(*Out, Operand, PrintName, TypeNames, &Table); + WriteAsOperandInternal(*Out, Operand, PrintName, TypeNames, &Machine); } @@ -674,7 +767,7 @@ void AssemblyWriter::printFunction(const Function *F) { else *Out << "\"\""; *Out << "("; - Table.incorporateFunction(F); + Machine.incorporateFunction(F); // Loop over the arguments, printing them... const FunctionType *FT = F->getFunctionType(); @@ -701,7 +794,7 @@ void AssemblyWriter::printFunction(const Function *F) { *Out << "}\n"; } - Table.purgeFunction(); + Machine.purgeFunction(); } /// printArgument - This member is called for every argument that is passed into @@ -717,8 +810,6 @@ void AssemblyWriter::printArgument(const Argument *Arg) { // Output name, if available... if (Arg->hasName()) *Out << " " << getLLVMName(Arg->getName()); - else if (Table.getSlot(Arg) < 0) - *Out << ""; } /// printBasicBlock - This member is called for each basic block in a method. @@ -727,12 +818,7 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (BB->hasName()) { // Print out the label if it exists... *Out << "\n" << BB->getName() << ":"; } else if (!BB->use_empty()) { // Don't print block # of no uses... - int Slot = Table.getSlot(BB); - *Out << "\n;