diff options
author | Chris Lattner <sabre@nondot.org> | 2004-05-09 06:20:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-05-09 06:20:51 +0000 |
commit | 687580757216d1005bfb0aae201268cf8ab827ac (patch) | |
tree | 85c68da4f38a83e02df2103efa1771640ccd121a /lib | |
parent | b0fd761c3dd575f28c9584feeafef71d381a4bb1 (diff) | |
download | external_llvm-687580757216d1005bfb0aae201268cf8ab827ac.zip external_llvm-687580757216d1005bfb0aae201268cf8ab827ac.tar.gz external_llvm-687580757216d1005bfb0aae201268cf8ab827ac.tar.bz2 |
Make the floating point constant pools local to each function, split the
FindUsedTypes manipulation stuff out to be a seperate pass, and make the
main CWriter be a function pass now!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13435 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 211 | ||||
-rw-r--r-- | lib/Target/CBackend/Writer.cpp | 211 |
2 files changed, 224 insertions, 198 deletions
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 41e5162..4fe8870 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -38,36 +38,49 @@ using namespace llvm; namespace { - class CWriter : public Pass, public InstVisitor<CWriter> { + /// NameAllUsedStructs - This pass inserts names for any unnamed structure + /// types that are used by the program. + /// + class CBackendNameAllUsedStructs : public Pass { + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<FindUsedTypes>(); + } + + virtual const char *getPassName() const { + return "C backend type canonicalizer"; + } + + virtual bool run(Module &M); + }; + + /// CWriter - This class is the main chunk of code that converts an LLVM + /// module to a C translation unit. + class CWriter : public FunctionPass, public InstVisitor<CWriter> { std::ostream &Out; IntrinsicLowering &IL; Mangler *Mang; const Module *TheModule; - FindUsedTypes *FUT; - std::map<const Type *, std::string> TypeNames; std::map<const ConstantFP *, unsigned> FPConstantMap; public: CWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {} - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<FindUsedTypes>(); - } - virtual const char *getPassName() const { return "C backend"; } - bool doInitialization(Module &M); - bool run(Module &M) { - doInitialization(M); + virtual bool doInitialization(Module &M); - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal()) { - // First pass, lower all unhandled intrinsics. - lowerIntrinsics(*I); - printFunction(*I); - } + bool runOnFunction(Function &F) { + // Output all floating point constants that cannot be printed accurately. + printFloatingPointConstants(F); + + lowerIntrinsics(F); + printFunction(F); + FPConstantMap.clear(); + return false; + } + virtual bool doFinalization(Module &M) { // Free memory... delete Mang; TypeNames.clear(); @@ -86,9 +99,9 @@ namespace { bool nameAllUsedStructureTypes(Module &M); void printModule(Module *M); - void printFloatingPointConstants(Module &M); - void printSymbolTable(const SymbolTable &ST); + void printModuleTypes(const SymbolTable &ST); void printContainedStructs(const Type *Ty, std::set<const StructType *> &); + void printFloatingPointConstants(Function &F); void printFunctionSignature(const Function *F, bool Prototype); void printFunction(Function &); @@ -172,6 +185,46 @@ namespace { }; } +/// This method inserts names for any unnamed structure types that are used by +/// the program, and removes names from structure types that are not used by the +/// program. +/// +bool CBackendNameAllUsedStructs::run(Module &M) { + // Get a set of types that are used by the program... + std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes(); + + // Loop over the module symbol table, removing types from UT that are + // already named, and removing names for structure types that are not used. + // + SymbolTable &MST = M.getSymbolTable(); + if (MST.find(Type::TypeTy) != MST.end()) + for (SymbolTable::type_iterator I = MST.type_begin(Type::TypeTy), + E = MST.type_end(Type::TypeTy); I != E; ) { + SymbolTable::type_iterator It = I++; + if (StructType *STy = dyn_cast<StructType>(It->second)) { + // If this is not used, remove it from the symbol table. + std::set<const Type *>::iterator UTI = UT.find(STy); + if (UTI == UT.end()) + MST.remove(It->first, It->second); + else + UT.erase(UTI); + } + } + + // UT now contains types that are not named. Loop over it, naming + // structure types. + // + bool Changed = false; + for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end(); + I != E; ++I) + if (const StructType *ST = dyn_cast<StructType>(*I)) { + ((Value*)ST)->setName("unnamed", &MST); + Changed = true; + } + return Changed; +} + + // Pass the Type* and the variable name and this prints out the variable // declaration. // @@ -578,36 +631,6 @@ void CWriter::writeOperand(Value *Operand) { Out << ")"; } -// nameAllUsedStructureTypes - If there are structure types in the module that -// are used but do not have names assigned to them in the symbol table yet then -// we assign them names now. -// -bool CWriter::nameAllUsedStructureTypes(Module &M) { - // Get a set of types that are used by the program... - std::set<const Type *> UT = FUT->getTypes(); - - // Loop over the module symbol table, removing types from UT that are already - // named. - // - SymbolTable &MST = M.getSymbolTable(); - if (MST.find(Type::TypeTy) != MST.end()) - for (SymbolTable::type_iterator I = MST.type_begin(Type::TypeTy), - E = MST.type_end(Type::TypeTy); I != E; ++I) - UT.erase(cast<Type>(I->second)); - - // UT now contains types that are not named. Loop over it, naming structure - // types. - // - bool Changed = false; - for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end(); - I != E; ++I) - if (const StructType *ST = dyn_cast<StructType>(*I)) { - ((Value*)ST)->setName("unnamed", &MST); - Changed = true; - } - return Changed; -} - // generateCompilerSpecificCode - This is where we add conditional compilation // directives to cater to specific compilers as need be. // @@ -654,12 +677,10 @@ static void generateCompilerSpecificCode(std::ostream& Out) { bool CWriter::doInitialization(Module &M) { // Initialize TheModule = &M; - FUT = &getAnalysis<FindUsedTypes>(); IL.AddPrototypes(M); // Ensure that all structure types have names... - bool Changed = nameAllUsedStructureTypes(M); Mang = new Mangler(M); // get declaration for alloca @@ -683,7 +704,7 @@ bool CWriter::doInitialization(Module &M) { // // Loop over the symbol table, emitting all named constants... - printSymbolTable(M.getSymbolTable()); + printModuleTypes(M.getSymbolTable()); // Global variable declarations... if (!M.gempty()) { @@ -765,9 +786,6 @@ bool CWriter::doInitialization(Module &M) { } } - // Output all floating point constants that cannot be printed accurately... - printFloatingPointConstants(M); - if (!M.empty()) Out << "\n\n/* Function Bodies */\n"; return false; @@ -775,7 +793,7 @@ bool CWriter::doInitialization(Module &M) { /// Output all floating point constants that cannot be printed accurately... -void CWriter::printFloatingPointConstants(Module &M) { +void CWriter::printFloatingPointConstants(Function &F) { union { double D; uint64_t U; @@ -791,39 +809,38 @@ void CWriter::printFloatingPointConstants(Module &M) { // the precision of the printed form, unless the printed form preserves // precision. // - unsigned FPCounter = 0; - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) - for (constant_iterator I = constant_begin(F), E = constant_end(F); - I != E; ++I) - if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I)) - if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. - !FPConstantMap.count(FPC)) { - double Val = FPC->getValue(); - - FPConstantMap[FPC] = FPCounter; // Number the FP constants - - if (FPC->getType() == Type::DoubleTy) { - DBLUnion.D = Val; - Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << DBLUnion.U << std::dec - << "ULL; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::FloatTy) { - FLTUnion.F = Val; - Out << "static const ConstantFloatTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << FLTUnion.U << std::dec - << "U; /* " << Val << " */\n"; - } else - assert(0 && "Unknown float type!"); - } + static unsigned FPCounter = 0; + for (constant_iterator I = constant_begin(&F), E = constant_end(&F); + I != E; ++I) + if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I)) + if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. + !FPConstantMap.count(FPC)) { + double Val = FPC->getValue(); + + FPConstantMap[FPC] = FPCounter; // Number the FP constants + + if (FPC->getType() == Type::DoubleTy) { + DBLUnion.D = Val; + Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ + << " = 0x" << std::hex << DBLUnion.U << std::dec + << "ULL; /* " << Val << " */\n"; + } else if (FPC->getType() == Type::FloatTy) { + FLTUnion.F = Val; + Out << "static const ConstantFloatTy FPConstant" << FPCounter++ + << " = 0x" << std::hex << FLTUnion.U << std::dec + << "U; /* " << Val << " */\n"; + } else + assert(0 && "Unknown float type!"); + } Out << "\n"; - } +} /// printSymbolTable - Run through symbol table looking for type names. If a /// type name is found, emit it's declaration... /// -void CWriter::printSymbolTable(const SymbolTable &ST) { +void CWriter::printModuleTypes(const SymbolTable &ST) { // If there are no type names, exit early. if (ST.find(Type::TypeTy) == ST.end()) return; @@ -835,27 +852,23 @@ void CWriter::printSymbolTable(const SymbolTable &ST) { // Print out forward declarations for structure types before anything else! Out << "/* Structure forward decls */\n"; for (; I != End; ++I) - if (const Type *STy = dyn_cast<StructType>(I->second)) - // Only print out used types! - if (FUT->getTypes().count(STy)) { - std::string Name = "struct l_" + Mangler::makeNameProper(I->first); - Out << Name << ";\n"; - TypeNames.insert(std::make_pair(STy, Name)); - } + if (const Type *STy = dyn_cast<StructType>(I->second)) { + std::string Name = "struct l_" + Mangler::makeNameProper(I->first); + Out << Name << ";\n"; + TypeNames.insert(std::make_pair(STy, Name)); + } Out << "\n"; // Now we can print out typedefs... Out << "/* Typedefs */\n"; - for (I = ST.type_begin(Type::TypeTy); I != End; ++I) - // Only print out used types! - if (FUT->getTypes().count(cast<Type>(I->second))) { - const Type *Ty = cast<Type>(I->second); - std::string Name = "l_" + Mangler::makeNameProper(I->first); - Out << "typedef "; - printType(Out, Ty, Name); - Out << ";\n"; - } + for (I = ST.type_begin(Type::TypeTy); I != End; ++I) { + const Type *Ty = cast<Type>(I->second); + std::string Name = "l_" + Mangler::makeNameProper(I->first); + Out << "typedef "; + printType(Out, Ty, Name); + Out << ";\n"; + } Out << "\n"; @@ -869,8 +882,7 @@ void CWriter::printSymbolTable(const SymbolTable &ST) { for (I = ST.type_begin(Type::TypeTy); I != End; ++I) if (const StructType *STy = dyn_cast<StructType>(I->second)) // Only print out used types! - if (FUT->getTypes().count(STy)) - printContainedStructs(STy, StructPrinted); + printContainedStructs(STy, StructPrinted); } // Push the struct onto the stack and recursively push all structs @@ -1450,6 +1462,7 @@ void CWriter::visitVAArgInst(VAArgInst &I) { bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) { PM.add(createLowerAllocationsPass()); PM.add(createLowerInvokePass()); + PM.add(new CBackendNameAllUsedStructs()); PM.add(new CWriter(o, getIntrinsicLowering())); return false; } diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 41e5162..4fe8870 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -38,36 +38,49 @@ using namespace llvm; namespace { - class CWriter : public Pass, public InstVisitor<CWriter> { + /// NameAllUsedStructs - This pass inserts names for any unnamed structure + /// types that are used by the program. + /// + class CBackendNameAllUsedStructs : public Pass { + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<FindUsedTypes>(); + } + + virtual const char *getPassName() const { + return "C backend type canonicalizer"; + } + + virtual bool run(Module &M); + }; + + /// CWriter - This class is the main chunk of code that converts an LLVM + /// module to a C translation unit. + class CWriter : public FunctionPass, public InstVisitor<CWriter> { std::ostream &Out; IntrinsicLowering &IL; Mangler *Mang; const Module *TheModule; - FindUsedTypes *FUT; - std::map<const Type *, std::string> TypeNames; std::map<const ConstantFP *, unsigned> FPConstantMap; public: CWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {} - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<FindUsedTypes>(); - } - virtual const char *getPassName() const { return "C backend"; } - bool doInitialization(Module &M); - bool run(Module &M) { - doInitialization(M); + virtual bool doInitialization(Module &M); - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal()) { - // First pass, lower all unhandled intrinsics. - lowerIntrinsics(*I); - printFunction(*I); - } + bool runOnFunction(Function &F) { + // Output all floating point constants that cannot be printed accurately. + printFloatingPointConstants(F); + + lowerIntrinsics(F); + printFunction(F); + FPConstantMap.clear(); + return false; + } + virtual bool doFinalization(Module &M) { // Free memory... delete Mang; TypeNames.clear(); @@ -86,9 +99,9 @@ namespace { bool nameAllUsedStructureTypes(Module &M); void printModule(Module *M); - void printFloatingPointConstants(Module &M); - void printSymbolTable(const SymbolTable &ST); + void printModuleTypes(const SymbolTable &ST); void printContainedStructs(const Type *Ty, std::set<const StructType *> &); + void printFloatingPointConstants(Function &F); void printFunctionSignature(const Function *F, bool Prototype); void printFunction(Function &); @@ -172,6 +185,46 @@ namespace { }; } +/// This method inserts names for any unnamed structure types that are used by +/// the program, and removes names from structure types that are not used by the +/// program. +/// +bool CBackendNameAllUsedStructs::run(Module &M) { + // Get a set of types that are used by the program... + std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes(); + + // Loop over the module symbol table, removing types from UT that are + // already named, and removing names for structure types that are not used. + // + SymbolTable &MST = M.getSymbolTable(); + if (MST.find(Type::TypeTy) != MST.end()) + for (SymbolTable::type_iterator I = MST.type_begin(Type::TypeTy), + E = MST.type_end(Type::TypeTy); I != E; ) { + SymbolTable::type_iterator It = I++; + if (StructType *STy = dyn_cast<StructType>(It->second)) { + // If this is not used, remove it from the symbol table. + std::set<const Type *>::iterator UTI = UT.find(STy); + if (UTI == UT.end()) + MST.remove(It->first, It->second); + else + UT.erase(UTI); + } + } + + // UT now contains types that are not named. Loop over it, naming + // structure types. + // + bool Changed = false; + for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end(); + I != E; ++I) + if (const StructType *ST = dyn_cast<StructType>(*I)) { + ((Value*)ST)->setName("unnamed", &MST); + Changed = true; + } + return Changed; +} + + // Pass the Type* and the variable name and this prints out the variable // declaration. // @@ -578,36 +631,6 @@ void CWriter::writeOperand(Value *Operand) { Out << ")"; } -// nameAllUsedStructureTypes - If there are structure types in the module that -// are used but do not have names assigned to them in the symbol table yet then -// we assign them names now. -// -bool CWriter::nameAllUsedStructureTypes(Module &M) { - // Get a set of types that are used by the program... - std::set<const Type *> UT = FUT->getTypes(); - - // Loop over the module symbol table, removing types from UT that are already - // named. - // - SymbolTable &MST = M.getSymbolTable(); - if (MST.find(Type::TypeTy) != MST.end()) - for (SymbolTable::type_iterator I = MST.type_begin(Type::TypeTy), - E = MST.type_end(Type::TypeTy); I != E; ++I) - UT.erase(cast<Type>(I->second)); - - // UT now contains types that are not named. Loop over it, naming structure - // types. - // - bool Changed = false; - for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end(); - I != E; ++I) - if (const StructType *ST = dyn_cast<StructType>(*I)) { - ((Value*)ST)->setName("unnamed", &MST); - Changed = true; - } - return Changed; -} - // generateCompilerSpecificCode - This is where we add conditional compilation // directives to cater to specific compilers as need be. // @@ -654,12 +677,10 @@ static void generateCompilerSpecificCode(std::ostream& Out) { bool CWriter::doInitialization(Module &M) { // Initialize TheModule = &M; - FUT = &getAnalysis<FindUsedTypes>(); IL.AddPrototypes(M); // Ensure that all structure types have names... - bool Changed = nameAllUsedStructureTypes(M); Mang = new Mangler(M); // get declaration for alloca @@ -683,7 +704,7 @@ bool CWriter::doInitialization(Module &M) { // // Loop over the symbol table, emitting all named constants... - printSymbolTable(M.getSymbolTable()); + printModuleTypes(M.getSymbolTable()); // Global variable declarations... if (!M.gempty()) { @@ -765,9 +786,6 @@ bool CWriter::doInitialization(Module &M) { } } - // Output all floating point constants that cannot be printed accurately... - printFloatingPointConstants(M); - if (!M.empty()) Out << "\n\n/* Function Bodies */\n"; return false; @@ -775,7 +793,7 @@ bool CWriter::doInitialization(Module &M) { /// Output all floating point constants that cannot be printed accurately... -void CWriter::printFloatingPointConstants(Module &M) { +void CWriter::printFloatingPointConstants(Function &F) { union { double D; uint64_t U; @@ -791,39 +809,38 @@ void CWriter::printFloatingPointConstants(Module &M) { // the precision of the printed form, unless the printed form preserves // precision. // - unsigned FPCounter = 0; - for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) - for (constant_iterator I = constant_begin(F), E = constant_end(F); - I != E; ++I) - if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I)) - if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. - !FPConstantMap.count(FPC)) { - double Val = FPC->getValue(); - - FPConstantMap[FPC] = FPCounter; // Number the FP constants - - if (FPC->getType() == Type::DoubleTy) { - DBLUnion.D = Val; - Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << DBLUnion.U << std::dec - << "ULL; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::FloatTy) { - FLTUnion.F = Val; - Out << "static const ConstantFloatTy FPConstant" << FPCounter++ - << " = 0x" << std::hex << FLTUnion.U << std::dec - << "U; /* " << Val << " */\n"; - } else - assert(0 && "Unknown float type!"); - } + static unsigned FPCounter = 0; + for (constant_iterator I = constant_begin(&F), E = constant_end(&F); + I != E; ++I) + if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I)) + if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. + !FPConstantMap.count(FPC)) { + double Val = FPC->getValue(); + + FPConstantMap[FPC] = FPCounter; // Number the FP constants + + if (FPC->getType() == Type::DoubleTy) { + DBLUnion.D = Val; + Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ + << " = 0x" << std::hex << DBLUnion.U << std::dec + << "ULL; /* " << Val << " */\n"; + } else if (FPC->getType() == Type::FloatTy) { + FLTUnion.F = Val; + Out << "static const ConstantFloatTy FPConstant" << FPCounter++ + << " = 0x" << std::hex << FLTUnion.U << std::dec + << "U; /* " << Val << " */\n"; + } else + assert(0 && "Unknown float type!"); + } Out << "\n"; - } +} /// printSymbolTable - Run through symbol table looking for type names. If a /// type name is found, emit it's declaration... /// -void CWriter::printSymbolTable(const SymbolTable &ST) { +void CWriter::printModuleTypes(const SymbolTable &ST) { // If there are no type names, exit early. if (ST.find(Type::TypeTy) == ST.end()) return; @@ -835,27 +852,23 @@ void CWriter::printSymbolTable(const SymbolTable &ST) { // Print out forward declarations for structure types before anything else! Out << "/* Structure forward decls */\n"; for (; I != End; ++I) - if (const Type *STy = dyn_cast<StructType>(I->second)) - // Only print out used types! - if (FUT->getTypes().count(STy)) { - std::string Name = "struct l_" + Mangler::makeNameProper(I->first); - Out << Name << ";\n"; - TypeNames.insert(std::make_pair(STy, Name)); - } + if (const Type *STy = dyn_cast<StructType>(I->second)) { + std::string Name = "struct l_" + Mangler::makeNameProper(I->first); + Out << Name << ";\n"; + TypeNames.insert(std::make_pair(STy, Name)); + } Out << "\n"; // Now we can print out typedefs... Out << "/* Typedefs */\n"; - for (I = ST.type_begin(Type::TypeTy); I != End; ++I) - // Only print out used types! - if (FUT->getTypes().count(cast<Type>(I->second))) { - const Type *Ty = cast<Type>(I->second); - std::string Name = "l_" + Mangler::makeNameProper(I->first); - Out << "typedef "; - printType(Out, Ty, Name); - Out << ";\n"; - } + for (I = ST.type_begin(Type::TypeTy); I != End; ++I) { + const Type *Ty = cast<Type>(I->second); + std::string Name = "l_" + Mangler::makeNameProper(I->first); + Out << "typedef "; + printType(Out, Ty, Name); + Out << ";\n"; + } Out << "\n"; @@ -869,8 +882,7 @@ void CWriter::printSymbolTable(const SymbolTable &ST) { for (I = ST.type_begin(Type::TypeTy); I != End; ++I) if (const StructType *STy = dyn_cast<StructType>(I->second)) // Only print out used types! - if (FUT->getTypes().count(STy)) - printContainedStructs(STy, StructPrinted); + printContainedStructs(STy, StructPrinted); } // Push the struct onto the stack and recursively push all structs @@ -1450,6 +1462,7 @@ void CWriter::visitVAArgInst(VAArgInst &I) { bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) { PM.add(createLowerAllocationsPass()); PM.add(createLowerInvokePass()); + PM.add(new CBackendNameAllUsedStructs()); PM.add(new CWriter(o, getIntrinsicLowering())); return false; } |