Two things:

1. Don't emit debug info, or other llvm.metadata to the .cbe.c file.
2. Mark static ctors/dtors as such, so that bugpoint works on C++ code
   compiled with the new CFE.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26602 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2006-03-07 22:58:23 +00:00
parent 41dd39ee01
commit 9a571ba823
2 changed files with 178 additions and 24 deletions

View File

@ -797,7 +797,7 @@ void CWriter::writeOperand(Value *Operand) {
// directives to cater to specific compilers as need be. // directives to cater to specific compilers as need be.
// //
static void generateCompilerSpecificCode(std::ostream& Out) { static void generateCompilerSpecificCode(std::ostream& Out) {
// Alloca is hard to get, and we don't want to include stdlib.h here... // Alloca is hard to get, and we don't want to include stdlib.h here.
Out << "/* get a declaration for alloca */\n" Out << "/* get a declaration for alloca */\n"
<< "#if defined(__CYGWIN__)\n" << "#if defined(__CYGWIN__)\n"
<< "extern void *_alloca(unsigned long);\n" << "extern void *_alloca(unsigned long);\n"
@ -885,6 +885,8 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
<< "#define LLVM_INFF __builtin_inff() /* Float */\n" << "#define LLVM_INFF __builtin_inff() /* Float */\n"
<< "#define LLVM_PREFETCH(addr,rw,locality) " << "#define LLVM_PREFETCH(addr,rw,locality) "
"__builtin_prefetch(addr,rw,locality)\n" "__builtin_prefetch(addr,rw,locality)\n"
<< "#define __ATTRIBUTE_CTOR__ __attribute__((constructor))\n"
<< "#define __ATTRIBUTE_DTOR__ __attribute__((destructor))\n"
<< "#else\n" << "#else\n"
<< "#define LLVM_NAN(NanStr) ((double)0.0) /* Double */\n" << "#define LLVM_NAN(NanStr) ((double)0.0) /* Double */\n"
<< "#define LLVM_NANF(NanStr) 0.0F /* Float */\n" << "#define LLVM_NANF(NanStr) 0.0F /* Float */\n"
@ -893,6 +895,8 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
<< "#define LLVM_INF ((double)0.0) /* Double */\n" << "#define LLVM_INF ((double)0.0) /* Double */\n"
<< "#define LLVM_INFF 0.0F /* Float */\n" << "#define LLVM_INFF 0.0F /* Float */\n"
<< "#define LLVM_PREFETCH(addr,rw,locality) /* PREFETCH */\n" << "#define LLVM_PREFETCH(addr,rw,locality) /* PREFETCH */\n"
<< "#define __ATTRIBUTE_CTOR__\n"
<< "#define __ATTRIBUTE_DTOR__\n"
<< "#endif\n\n"; << "#endif\n\n";
// Output target-specific code that should be inserted into main. // Output target-specific code that should be inserted into main.
@ -908,6 +912,53 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
} }
/// FindStaticTors - Given a static ctor/dtor list, unpack its contents into
/// the StaticTors set.
static void FindStaticTors(GlobalVariable *GV, std::set<Function*> &StaticTors){
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
if (!InitList) return;
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){
if (CS->getNumOperands() != 2) return; // Not array of 2-element structs.
if (CS->getOperand(1)->isNullValue())
return; // Found a null terminator, exit printing.
Constant *FP = CS->getOperand(1);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
if (CE->getOpcode() == Instruction::Cast)
FP = CE->getOperand(0);
if (Function *F = dyn_cast<Function>(FP))
StaticTors.insert(F);
}
}
enum SpecialGlobalClass {
NotSpecial = 0,
GlobalCtors, GlobalDtors,
NotPrinted
};
/// getGlobalVariableClass - If this is a global that is specially recognized
/// by LLVM, return a code that indicates how we should handle it.
static SpecialGlobalClass getGlobalVariableClass(const GlobalVariable *GV) {
// If this is a global ctors/dtors list, handle it now.
if (GV->hasAppendingLinkage() && GV->use_empty()) {
if (GV->getName() == "llvm.global_ctors")
return GlobalCtors;
else if (GV->getName() == "llvm.global_dtors")
return GlobalDtors;
}
// Otherwise, it it is other metadata, don't print it. This catches things
// like debug information.
if (GV->getSection() == "llvm.metadata")
return NotPrinted;
return NotSpecial;
}
bool CWriter::doInitialization(Module &M) { bool CWriter::doInitialization(Module &M) {
// Initialize // Initialize
TheModule = &M; TheModule = &M;
@ -918,6 +969,22 @@ bool CWriter::doInitialization(Module &M) {
Mang = new Mangler(M); Mang = new Mangler(M);
Mang->markCharUnacceptable('.'); Mang->markCharUnacceptable('.');
// Keep track of which functions are static ctors/dtors so they can have
// an attribute added to their prototypes.
std::set<Function*> StaticCtors, StaticDtors;
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
switch (getGlobalVariableClass(I)) {
default: break;
case GlobalCtors:
FindStaticTors(I, StaticCtors);
break;
case GlobalDtors:
FindStaticTors(I, StaticDtors);
break;
}
}
// get declaration for alloca // get declaration for alloca
Out << "/* Provide Declarations */\n"; Out << "/* Provide Declarations */\n";
Out << "#include <stdarg.h>\n"; // Varargs support Out << "#include <stdarg.h>\n"; // Varargs support
@ -955,20 +1022,22 @@ bool CWriter::doInitialization(Module &M) {
} }
// Function declarations // Function declarations
Out << "\n/* Function Declarations */\n";
Out << "double fmod(double, double);\n"; // Support for FP rem Out << "double fmod(double, double);\n"; // Support for FP rem
Out << "float fmodf(float, float);\n"; Out << "float fmodf(float, float);\n";
if (!M.empty()) { for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
Out << "\n/* Function Declarations */\n"; // Don't print declarations for intrinsic functions.
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!I->getIntrinsicID() &&
// Don't print declarations for intrinsic functions. I->getName() != "setjmp" && I->getName() != "longjmp") {
if (!I->getIntrinsicID() && printFunctionSignature(I, true);
I->getName() != "setjmp" && I->getName() != "longjmp") { if (I->hasWeakLinkage() || I->hasLinkOnceLinkage())
printFunctionSignature(I, true); Out << " __ATTRIBUTE_WEAK__";
if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; if (StaticCtors.count(I))
if (I->hasLinkOnceLinkage()) Out << " __ATTRIBUTE_WEAK__"; Out << " __ATTRIBUTE_CTOR__";
Out << ";\n"; if (StaticDtors.count(I))
} Out << " __ATTRIBUTE_DTOR__";
Out << ";\n";
} }
} }
@ -978,6 +1047,10 @@ bool CWriter::doInitialization(Module &M) {
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) I != E; ++I)
if (!I->isExternal()) { if (!I->isExternal()) {
// Ignore special globals, such as debug info.
if (getGlobalVariableClass(I))
continue;
if (I->hasInternalLinkage()) if (I->hasInternalLinkage())
Out << "static "; Out << "static ";
else else
@ -998,6 +1071,10 @@ bool CWriter::doInitialization(Module &M) {
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) I != E; ++I)
if (!I->isExternal()) { if (!I->isExternal()) {
// Ignore special globals, such as debug info.
if (getGlobalVariableClass(I))
continue;
if (I->hasInternalLinkage()) if (I->hasInternalLinkage())
Out << "static "; Out << "static ";
printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); printType(Out, I->getType()->getElementType(), Mang->getValueName(I));

View File

@ -797,7 +797,7 @@ void CWriter::writeOperand(Value *Operand) {
// directives to cater to specific compilers as need be. // directives to cater to specific compilers as need be.
// //
static void generateCompilerSpecificCode(std::ostream& Out) { static void generateCompilerSpecificCode(std::ostream& Out) {
// Alloca is hard to get, and we don't want to include stdlib.h here... // Alloca is hard to get, and we don't want to include stdlib.h here.
Out << "/* get a declaration for alloca */\n" Out << "/* get a declaration for alloca */\n"
<< "#if defined(__CYGWIN__)\n" << "#if defined(__CYGWIN__)\n"
<< "extern void *_alloca(unsigned long);\n" << "extern void *_alloca(unsigned long);\n"
@ -885,6 +885,8 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
<< "#define LLVM_INFF __builtin_inff() /* Float */\n" << "#define LLVM_INFF __builtin_inff() /* Float */\n"
<< "#define LLVM_PREFETCH(addr,rw,locality) " << "#define LLVM_PREFETCH(addr,rw,locality) "
"__builtin_prefetch(addr,rw,locality)\n" "__builtin_prefetch(addr,rw,locality)\n"
<< "#define __ATTRIBUTE_CTOR__ __attribute__((constructor))\n"
<< "#define __ATTRIBUTE_DTOR__ __attribute__((destructor))\n"
<< "#else\n" << "#else\n"
<< "#define LLVM_NAN(NanStr) ((double)0.0) /* Double */\n" << "#define LLVM_NAN(NanStr) ((double)0.0) /* Double */\n"
<< "#define LLVM_NANF(NanStr) 0.0F /* Float */\n" << "#define LLVM_NANF(NanStr) 0.0F /* Float */\n"
@ -893,6 +895,8 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
<< "#define LLVM_INF ((double)0.0) /* Double */\n" << "#define LLVM_INF ((double)0.0) /* Double */\n"
<< "#define LLVM_INFF 0.0F /* Float */\n" << "#define LLVM_INFF 0.0F /* Float */\n"
<< "#define LLVM_PREFETCH(addr,rw,locality) /* PREFETCH */\n" << "#define LLVM_PREFETCH(addr,rw,locality) /* PREFETCH */\n"
<< "#define __ATTRIBUTE_CTOR__\n"
<< "#define __ATTRIBUTE_DTOR__\n"
<< "#endif\n\n"; << "#endif\n\n";
// Output target-specific code that should be inserted into main. // Output target-specific code that should be inserted into main.
@ -908,6 +912,53 @@ static void generateCompilerSpecificCode(std::ostream& Out) {
} }
/// FindStaticTors - Given a static ctor/dtor list, unpack its contents into
/// the StaticTors set.
static void FindStaticTors(GlobalVariable *GV, std::set<Function*> &StaticTors){
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
if (!InitList) return;
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){
if (CS->getNumOperands() != 2) return; // Not array of 2-element structs.
if (CS->getOperand(1)->isNullValue())
return; // Found a null terminator, exit printing.
Constant *FP = CS->getOperand(1);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
if (CE->getOpcode() == Instruction::Cast)
FP = CE->getOperand(0);
if (Function *F = dyn_cast<Function>(FP))
StaticTors.insert(F);
}
}
enum SpecialGlobalClass {
NotSpecial = 0,
GlobalCtors, GlobalDtors,
NotPrinted
};
/// getGlobalVariableClass - If this is a global that is specially recognized
/// by LLVM, return a code that indicates how we should handle it.
static SpecialGlobalClass getGlobalVariableClass(const GlobalVariable *GV) {
// If this is a global ctors/dtors list, handle it now.
if (GV->hasAppendingLinkage() && GV->use_empty()) {
if (GV->getName() == "llvm.global_ctors")
return GlobalCtors;
else if (GV->getName() == "llvm.global_dtors")
return GlobalDtors;
}
// Otherwise, it it is other metadata, don't print it. This catches things
// like debug information.
if (GV->getSection() == "llvm.metadata")
return NotPrinted;
return NotSpecial;
}
bool CWriter::doInitialization(Module &M) { bool CWriter::doInitialization(Module &M) {
// Initialize // Initialize
TheModule = &M; TheModule = &M;
@ -918,6 +969,22 @@ bool CWriter::doInitialization(Module &M) {
Mang = new Mangler(M); Mang = new Mangler(M);
Mang->markCharUnacceptable('.'); Mang->markCharUnacceptable('.');
// Keep track of which functions are static ctors/dtors so they can have
// an attribute added to their prototypes.
std::set<Function*> StaticCtors, StaticDtors;
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
switch (getGlobalVariableClass(I)) {
default: break;
case GlobalCtors:
FindStaticTors(I, StaticCtors);
break;
case GlobalDtors:
FindStaticTors(I, StaticDtors);
break;
}
}
// get declaration for alloca // get declaration for alloca
Out << "/* Provide Declarations */\n"; Out << "/* Provide Declarations */\n";
Out << "#include <stdarg.h>\n"; // Varargs support Out << "#include <stdarg.h>\n"; // Varargs support
@ -955,20 +1022,22 @@ bool CWriter::doInitialization(Module &M) {
} }
// Function declarations // Function declarations
Out << "\n/* Function Declarations */\n";
Out << "double fmod(double, double);\n"; // Support for FP rem Out << "double fmod(double, double);\n"; // Support for FP rem
Out << "float fmodf(float, float);\n"; Out << "float fmodf(float, float);\n";
if (!M.empty()) { for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
Out << "\n/* Function Declarations */\n"; // Don't print declarations for intrinsic functions.
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!I->getIntrinsicID() &&
// Don't print declarations for intrinsic functions. I->getName() != "setjmp" && I->getName() != "longjmp") {
if (!I->getIntrinsicID() && printFunctionSignature(I, true);
I->getName() != "setjmp" && I->getName() != "longjmp") { if (I->hasWeakLinkage() || I->hasLinkOnceLinkage())
printFunctionSignature(I, true); Out << " __ATTRIBUTE_WEAK__";
if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; if (StaticCtors.count(I))
if (I->hasLinkOnceLinkage()) Out << " __ATTRIBUTE_WEAK__"; Out << " __ATTRIBUTE_CTOR__";
Out << ";\n"; if (StaticDtors.count(I))
} Out << " __ATTRIBUTE_DTOR__";
Out << ";\n";
} }
} }
@ -978,6 +1047,10 @@ bool CWriter::doInitialization(Module &M) {
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) I != E; ++I)
if (!I->isExternal()) { if (!I->isExternal()) {
// Ignore special globals, such as debug info.
if (getGlobalVariableClass(I))
continue;
if (I->hasInternalLinkage()) if (I->hasInternalLinkage())
Out << "static "; Out << "static ";
else else
@ -998,6 +1071,10 @@ bool CWriter::doInitialization(Module &M) {
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) I != E; ++I)
if (!I->isExternal()) { if (!I->isExternal()) {
// Ignore special globals, such as debug info.
if (getGlobalVariableClass(I))
continue;
if (I->hasInternalLinkage()) if (I->hasInternalLinkage())
Out << "static "; Out << "static ";
printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); printType(Out, I->getType()->getElementType(), Mang->getValueName(I));