mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-05 01:56:16 +00:00
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
This commit is contained in:
parent
b0fd761c3d
commit
6875807572
@ -38,36 +38,49 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
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;
|
std::ostream &Out;
|
||||||
IntrinsicLowering &IL;
|
IntrinsicLowering &IL;
|
||||||
Mangler *Mang;
|
Mangler *Mang;
|
||||||
const Module *TheModule;
|
const Module *TheModule;
|
||||||
FindUsedTypes *FUT;
|
|
||||||
|
|
||||||
std::map<const Type *, std::string> TypeNames;
|
std::map<const Type *, std::string> TypeNames;
|
||||||
|
|
||||||
std::map<const ConstantFP *, unsigned> FPConstantMap;
|
std::map<const ConstantFP *, unsigned> FPConstantMap;
|
||||||
public:
|
public:
|
||||||
CWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {}
|
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"; }
|
virtual const char *getPassName() const { return "C backend"; }
|
||||||
|
|
||||||
bool doInitialization(Module &M);
|
virtual bool doInitialization(Module &M);
|
||||||
bool run(Module &M) {
|
|
||||||
doInitialization(M);
|
|
||||||
|
|
||||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
bool runOnFunction(Function &F) {
|
||||||
if (!I->isExternal()) {
|
// Output all floating point constants that cannot be printed accurately.
|
||||||
// First pass, lower all unhandled intrinsics.
|
printFloatingPointConstants(F);
|
||||||
lowerIntrinsics(*I);
|
|
||||||
printFunction(*I);
|
lowerIntrinsics(F);
|
||||||
}
|
printFunction(F);
|
||||||
|
FPConstantMap.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool doFinalization(Module &M) {
|
||||||
// Free memory...
|
// Free memory...
|
||||||
delete Mang;
|
delete Mang;
|
||||||
TypeNames.clear();
|
TypeNames.clear();
|
||||||
@ -86,9 +99,9 @@ namespace {
|
|||||||
|
|
||||||
bool nameAllUsedStructureTypes(Module &M);
|
bool nameAllUsedStructureTypes(Module &M);
|
||||||
void printModule(Module *M);
|
void printModule(Module *M);
|
||||||
void printFloatingPointConstants(Module &M);
|
void printModuleTypes(const SymbolTable &ST);
|
||||||
void printSymbolTable(const SymbolTable &ST);
|
|
||||||
void printContainedStructs(const Type *Ty, std::set<const StructType *> &);
|
void printContainedStructs(const Type *Ty, std::set<const StructType *> &);
|
||||||
|
void printFloatingPointConstants(Function &F);
|
||||||
void printFunctionSignature(const Function *F, bool Prototype);
|
void printFunctionSignature(const Function *F, bool Prototype);
|
||||||
|
|
||||||
void printFunction(Function &);
|
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
|
// Pass the Type* and the variable name and this prints out the variable
|
||||||
// declaration.
|
// declaration.
|
||||||
//
|
//
|
||||||
@ -578,36 +631,6 @@ void CWriter::writeOperand(Value *Operand) {
|
|||||||
Out << ")";
|
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
|
// generateCompilerSpecificCode - This is where we add conditional compilation
|
||||||
// directives to cater to specific compilers as need be.
|
// directives to cater to specific compilers as need be.
|
||||||
//
|
//
|
||||||
@ -654,12 +677,10 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
|
|||||||
bool CWriter::doInitialization(Module &M) {
|
bool CWriter::doInitialization(Module &M) {
|
||||||
// Initialize
|
// Initialize
|
||||||
TheModule = &M;
|
TheModule = &M;
|
||||||
FUT = &getAnalysis<FindUsedTypes>();
|
|
||||||
|
|
||||||
IL.AddPrototypes(M);
|
IL.AddPrototypes(M);
|
||||||
|
|
||||||
// Ensure that all structure types have names...
|
// Ensure that all structure types have names...
|
||||||
bool Changed = nameAllUsedStructureTypes(M);
|
|
||||||
Mang = new Mangler(M);
|
Mang = new Mangler(M);
|
||||||
|
|
||||||
// get declaration for alloca
|
// get declaration for alloca
|
||||||
@ -683,7 +704,7 @@ bool CWriter::doInitialization(Module &M) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Loop over the symbol table, emitting all named constants...
|
// Loop over the symbol table, emitting all named constants...
|
||||||
printSymbolTable(M.getSymbolTable());
|
printModuleTypes(M.getSymbolTable());
|
||||||
|
|
||||||
// Global variable declarations...
|
// Global variable declarations...
|
||||||
if (!M.gempty()) {
|
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())
|
if (!M.empty())
|
||||||
Out << "\n\n/* Function Bodies */\n";
|
Out << "\n\n/* Function Bodies */\n";
|
||||||
return false;
|
return false;
|
||||||
@ -775,7 +793,7 @@ bool CWriter::doInitialization(Module &M) {
|
|||||||
|
|
||||||
|
|
||||||
/// Output all floating point constants that cannot be printed accurately...
|
/// Output all floating point constants that cannot be printed accurately...
|
||||||
void CWriter::printFloatingPointConstants(Module &M) {
|
void CWriter::printFloatingPointConstants(Function &F) {
|
||||||
union {
|
union {
|
||||||
double D;
|
double D;
|
||||||
uint64_t U;
|
uint64_t U;
|
||||||
@ -791,39 +809,38 @@ void CWriter::printFloatingPointConstants(Module &M) {
|
|||||||
// the precision of the printed form, unless the printed form preserves
|
// the precision of the printed form, unless the printed form preserves
|
||||||
// precision.
|
// precision.
|
||||||
//
|
//
|
||||||
unsigned FPCounter = 0;
|
static 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);
|
||||||
for (constant_iterator I = constant_begin(F), E = constant_end(F);
|
I != E; ++I)
|
||||||
I != E; ++I)
|
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
|
||||||
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
|
if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe.
|
||||||
if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe.
|
!FPConstantMap.count(FPC)) {
|
||||||
!FPConstantMap.count(FPC)) {
|
double Val = FPC->getValue();
|
||||||
double Val = FPC->getValue();
|
|
||||||
|
FPConstantMap[FPC] = FPCounter; // Number the FP constants
|
||||||
FPConstantMap[FPC] = FPCounter; // Number the FP constants
|
|
||||||
|
if (FPC->getType() == Type::DoubleTy) {
|
||||||
if (FPC->getType() == Type::DoubleTy) {
|
DBLUnion.D = Val;
|
||||||
DBLUnion.D = Val;
|
Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
|
||||||
Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
|
<< " = 0x" << std::hex << DBLUnion.U << std::dec
|
||||||
<< " = 0x" << std::hex << DBLUnion.U << std::dec
|
<< "ULL; /* " << Val << " */\n";
|
||||||
<< "ULL; /* " << Val << " */\n";
|
} else if (FPC->getType() == Type::FloatTy) {
|
||||||
} else if (FPC->getType() == Type::FloatTy) {
|
FLTUnion.F = Val;
|
||||||
FLTUnion.F = Val;
|
Out << "static const ConstantFloatTy FPConstant" << FPCounter++
|
||||||
Out << "static const ConstantFloatTy FPConstant" << FPCounter++
|
<< " = 0x" << std::hex << FLTUnion.U << std::dec
|
||||||
<< " = 0x" << std::hex << FLTUnion.U << std::dec
|
<< "U; /* " << Val << " */\n";
|
||||||
<< "U; /* " << Val << " */\n";
|
} else
|
||||||
} else
|
assert(0 && "Unknown float type!");
|
||||||
assert(0 && "Unknown float type!");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// printSymbolTable - Run through symbol table looking for type names. If a
|
/// printSymbolTable - Run through symbol table looking for type names. If a
|
||||||
/// type name is found, emit it's declaration...
|
/// 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 there are no type names, exit early.
|
||||||
if (ST.find(Type::TypeTy) == ST.end())
|
if (ST.find(Type::TypeTy) == ST.end())
|
||||||
return;
|
return;
|
||||||
@ -835,27 +852,23 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
|
|||||||
// Print out forward declarations for structure types before anything else!
|
// Print out forward declarations for structure types before anything else!
|
||||||
Out << "/* Structure forward decls */\n";
|
Out << "/* Structure forward decls */\n";
|
||||||
for (; I != End; ++I)
|
for (; I != End; ++I)
|
||||||
if (const Type *STy = dyn_cast<StructType>(I->second))
|
if (const Type *STy = dyn_cast<StructType>(I->second)) {
|
||||||
// Only print out used types!
|
std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
|
||||||
if (FUT->getTypes().count(STy)) {
|
Out << Name << ";\n";
|
||||||
std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
|
TypeNames.insert(std::make_pair(STy, Name));
|
||||||
Out << Name << ";\n";
|
}
|
||||||
TypeNames.insert(std::make_pair(STy, Name));
|
|
||||||
}
|
|
||||||
|
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
|
|
||||||
// Now we can print out typedefs...
|
// Now we can print out typedefs...
|
||||||
Out << "/* Typedefs */\n";
|
Out << "/* Typedefs */\n";
|
||||||
for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
|
for (I = ST.type_begin(Type::TypeTy); I != End; ++I) {
|
||||||
// Only print out used types!
|
const Type *Ty = cast<Type>(I->second);
|
||||||
if (FUT->getTypes().count(cast<Type>(I->second))) {
|
std::string Name = "l_" + Mangler::makeNameProper(I->first);
|
||||||
const Type *Ty = cast<Type>(I->second);
|
Out << "typedef ";
|
||||||
std::string Name = "l_" + Mangler::makeNameProper(I->first);
|
printType(Out, Ty, Name);
|
||||||
Out << "typedef ";
|
Out << ";\n";
|
||||||
printType(Out, Ty, Name);
|
}
|
||||||
Out << ";\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
|
|
||||||
@ -869,8 +882,7 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
|
|||||||
for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
|
for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
|
||||||
if (const StructType *STy = dyn_cast<StructType>(I->second))
|
if (const StructType *STy = dyn_cast<StructType>(I->second))
|
||||||
// Only print out used types!
|
// 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
|
// 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) {
|
bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) {
|
||||||
PM.add(createLowerAllocationsPass());
|
PM.add(createLowerAllocationsPass());
|
||||||
PM.add(createLowerInvokePass());
|
PM.add(createLowerInvokePass());
|
||||||
|
PM.add(new CBackendNameAllUsedStructs());
|
||||||
PM.add(new CWriter(o, getIntrinsicLowering()));
|
PM.add(new CWriter(o, getIntrinsicLowering()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -38,36 +38,49 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
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;
|
std::ostream &Out;
|
||||||
IntrinsicLowering &IL;
|
IntrinsicLowering &IL;
|
||||||
Mangler *Mang;
|
Mangler *Mang;
|
||||||
const Module *TheModule;
|
const Module *TheModule;
|
||||||
FindUsedTypes *FUT;
|
|
||||||
|
|
||||||
std::map<const Type *, std::string> TypeNames;
|
std::map<const Type *, std::string> TypeNames;
|
||||||
|
|
||||||
std::map<const ConstantFP *, unsigned> FPConstantMap;
|
std::map<const ConstantFP *, unsigned> FPConstantMap;
|
||||||
public:
|
public:
|
||||||
CWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {}
|
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"; }
|
virtual const char *getPassName() const { return "C backend"; }
|
||||||
|
|
||||||
bool doInitialization(Module &M);
|
virtual bool doInitialization(Module &M);
|
||||||
bool run(Module &M) {
|
|
||||||
doInitialization(M);
|
|
||||||
|
|
||||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
bool runOnFunction(Function &F) {
|
||||||
if (!I->isExternal()) {
|
// Output all floating point constants that cannot be printed accurately.
|
||||||
// First pass, lower all unhandled intrinsics.
|
printFloatingPointConstants(F);
|
||||||
lowerIntrinsics(*I);
|
|
||||||
printFunction(*I);
|
lowerIntrinsics(F);
|
||||||
}
|
printFunction(F);
|
||||||
|
FPConstantMap.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool doFinalization(Module &M) {
|
||||||
// Free memory...
|
// Free memory...
|
||||||
delete Mang;
|
delete Mang;
|
||||||
TypeNames.clear();
|
TypeNames.clear();
|
||||||
@ -86,9 +99,9 @@ namespace {
|
|||||||
|
|
||||||
bool nameAllUsedStructureTypes(Module &M);
|
bool nameAllUsedStructureTypes(Module &M);
|
||||||
void printModule(Module *M);
|
void printModule(Module *M);
|
||||||
void printFloatingPointConstants(Module &M);
|
void printModuleTypes(const SymbolTable &ST);
|
||||||
void printSymbolTable(const SymbolTable &ST);
|
|
||||||
void printContainedStructs(const Type *Ty, std::set<const StructType *> &);
|
void printContainedStructs(const Type *Ty, std::set<const StructType *> &);
|
||||||
|
void printFloatingPointConstants(Function &F);
|
||||||
void printFunctionSignature(const Function *F, bool Prototype);
|
void printFunctionSignature(const Function *F, bool Prototype);
|
||||||
|
|
||||||
void printFunction(Function &);
|
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
|
// Pass the Type* and the variable name and this prints out the variable
|
||||||
// declaration.
|
// declaration.
|
||||||
//
|
//
|
||||||
@ -578,36 +631,6 @@ void CWriter::writeOperand(Value *Operand) {
|
|||||||
Out << ")";
|
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
|
// generateCompilerSpecificCode - This is where we add conditional compilation
|
||||||
// directives to cater to specific compilers as need be.
|
// directives to cater to specific compilers as need be.
|
||||||
//
|
//
|
||||||
@ -654,12 +677,10 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
|
|||||||
bool CWriter::doInitialization(Module &M) {
|
bool CWriter::doInitialization(Module &M) {
|
||||||
// Initialize
|
// Initialize
|
||||||
TheModule = &M;
|
TheModule = &M;
|
||||||
FUT = &getAnalysis<FindUsedTypes>();
|
|
||||||
|
|
||||||
IL.AddPrototypes(M);
|
IL.AddPrototypes(M);
|
||||||
|
|
||||||
// Ensure that all structure types have names...
|
// Ensure that all structure types have names...
|
||||||
bool Changed = nameAllUsedStructureTypes(M);
|
|
||||||
Mang = new Mangler(M);
|
Mang = new Mangler(M);
|
||||||
|
|
||||||
// get declaration for alloca
|
// get declaration for alloca
|
||||||
@ -683,7 +704,7 @@ bool CWriter::doInitialization(Module &M) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Loop over the symbol table, emitting all named constants...
|
// Loop over the symbol table, emitting all named constants...
|
||||||
printSymbolTable(M.getSymbolTable());
|
printModuleTypes(M.getSymbolTable());
|
||||||
|
|
||||||
// Global variable declarations...
|
// Global variable declarations...
|
||||||
if (!M.gempty()) {
|
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())
|
if (!M.empty())
|
||||||
Out << "\n\n/* Function Bodies */\n";
|
Out << "\n\n/* Function Bodies */\n";
|
||||||
return false;
|
return false;
|
||||||
@ -775,7 +793,7 @@ bool CWriter::doInitialization(Module &M) {
|
|||||||
|
|
||||||
|
|
||||||
/// Output all floating point constants that cannot be printed accurately...
|
/// Output all floating point constants that cannot be printed accurately...
|
||||||
void CWriter::printFloatingPointConstants(Module &M) {
|
void CWriter::printFloatingPointConstants(Function &F) {
|
||||||
union {
|
union {
|
||||||
double D;
|
double D;
|
||||||
uint64_t U;
|
uint64_t U;
|
||||||
@ -791,39 +809,38 @@ void CWriter::printFloatingPointConstants(Module &M) {
|
|||||||
// the precision of the printed form, unless the printed form preserves
|
// the precision of the printed form, unless the printed form preserves
|
||||||
// precision.
|
// precision.
|
||||||
//
|
//
|
||||||
unsigned FPCounter = 0;
|
static 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);
|
||||||
for (constant_iterator I = constant_begin(F), E = constant_end(F);
|
I != E; ++I)
|
||||||
I != E; ++I)
|
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
|
||||||
if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I))
|
if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe.
|
||||||
if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe.
|
!FPConstantMap.count(FPC)) {
|
||||||
!FPConstantMap.count(FPC)) {
|
double Val = FPC->getValue();
|
||||||
double Val = FPC->getValue();
|
|
||||||
|
FPConstantMap[FPC] = FPCounter; // Number the FP constants
|
||||||
FPConstantMap[FPC] = FPCounter; // Number the FP constants
|
|
||||||
|
if (FPC->getType() == Type::DoubleTy) {
|
||||||
if (FPC->getType() == Type::DoubleTy) {
|
DBLUnion.D = Val;
|
||||||
DBLUnion.D = Val;
|
Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
|
||||||
Out << "static const ConstantDoubleTy FPConstant" << FPCounter++
|
<< " = 0x" << std::hex << DBLUnion.U << std::dec
|
||||||
<< " = 0x" << std::hex << DBLUnion.U << std::dec
|
<< "ULL; /* " << Val << " */\n";
|
||||||
<< "ULL; /* " << Val << " */\n";
|
} else if (FPC->getType() == Type::FloatTy) {
|
||||||
} else if (FPC->getType() == Type::FloatTy) {
|
FLTUnion.F = Val;
|
||||||
FLTUnion.F = Val;
|
Out << "static const ConstantFloatTy FPConstant" << FPCounter++
|
||||||
Out << "static const ConstantFloatTy FPConstant" << FPCounter++
|
<< " = 0x" << std::hex << FLTUnion.U << std::dec
|
||||||
<< " = 0x" << std::hex << FLTUnion.U << std::dec
|
<< "U; /* " << Val << " */\n";
|
||||||
<< "U; /* " << Val << " */\n";
|
} else
|
||||||
} else
|
assert(0 && "Unknown float type!");
|
||||||
assert(0 && "Unknown float type!");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// printSymbolTable - Run through symbol table looking for type names. If a
|
/// printSymbolTable - Run through symbol table looking for type names. If a
|
||||||
/// type name is found, emit it's declaration...
|
/// 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 there are no type names, exit early.
|
||||||
if (ST.find(Type::TypeTy) == ST.end())
|
if (ST.find(Type::TypeTy) == ST.end())
|
||||||
return;
|
return;
|
||||||
@ -835,27 +852,23 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
|
|||||||
// Print out forward declarations for structure types before anything else!
|
// Print out forward declarations for structure types before anything else!
|
||||||
Out << "/* Structure forward decls */\n";
|
Out << "/* Structure forward decls */\n";
|
||||||
for (; I != End; ++I)
|
for (; I != End; ++I)
|
||||||
if (const Type *STy = dyn_cast<StructType>(I->second))
|
if (const Type *STy = dyn_cast<StructType>(I->second)) {
|
||||||
// Only print out used types!
|
std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
|
||||||
if (FUT->getTypes().count(STy)) {
|
Out << Name << ";\n";
|
||||||
std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
|
TypeNames.insert(std::make_pair(STy, Name));
|
||||||
Out << Name << ";\n";
|
}
|
||||||
TypeNames.insert(std::make_pair(STy, Name));
|
|
||||||
}
|
|
||||||
|
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
|
|
||||||
// Now we can print out typedefs...
|
// Now we can print out typedefs...
|
||||||
Out << "/* Typedefs */\n";
|
Out << "/* Typedefs */\n";
|
||||||
for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
|
for (I = ST.type_begin(Type::TypeTy); I != End; ++I) {
|
||||||
// Only print out used types!
|
const Type *Ty = cast<Type>(I->second);
|
||||||
if (FUT->getTypes().count(cast<Type>(I->second))) {
|
std::string Name = "l_" + Mangler::makeNameProper(I->first);
|
||||||
const Type *Ty = cast<Type>(I->second);
|
Out << "typedef ";
|
||||||
std::string Name = "l_" + Mangler::makeNameProper(I->first);
|
printType(Out, Ty, Name);
|
||||||
Out << "typedef ";
|
Out << ";\n";
|
||||||
printType(Out, Ty, Name);
|
}
|
||||||
Out << ";\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
|
|
||||||
@ -869,8 +882,7 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
|
|||||||
for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
|
for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
|
||||||
if (const StructType *STy = dyn_cast<StructType>(I->second))
|
if (const StructType *STy = dyn_cast<StructType>(I->second))
|
||||||
// Only print out used types!
|
// 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
|
// 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) {
|
bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) {
|
||||||
PM.add(createLowerAllocationsPass());
|
PM.add(createLowerAllocationsPass());
|
||||||
PM.add(createLowerInvokePass());
|
PM.add(createLowerInvokePass());
|
||||||
|
PM.add(new CBackendNameAllUsedStructs());
|
||||||
PM.add(new CWriter(o, getIntrinsicLowering()));
|
PM.add(new CWriter(o, getIntrinsicLowering()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user