From: Chris Lattner Date: Fri, 13 Feb 2004 23:00:29 +0000 (+0000) Subject: Make the cwriter use the lowerinvoke pass so that it can either use "disabled excepti... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=94f4f8ea10b9a6eb87f27e8bed205b2f8feac3ae;p=oota-llvm.git Make the cwriter use the lowerinvoke pass so that it can either use "disabled exceptions" or "expensive exceptions" controlled by an option. Also refactor and eliminate a bunch of cruft. This is a temporary solution and causes millions of warnings to pour out of programs that use exceptions, but it should fix the problem with sparc and the 'write' declaration (PR190). Subsequent changes will make this stink much less git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11405 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 73f43416219..cd24e2765d7 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -18,10 +18,12 @@ #include "llvm/Module.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" +#include "llvm/PassManager.h" #include "llvm/SymbolTable.h" #include "llvm/Intrinsics.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/ConstantsScanner.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/InstVisitor.h" @@ -40,34 +42,31 @@ namespace { std::map TypeNames; std::set MangledGlobals; - bool needsMalloc, emittedInvoke; + bool needsMalloc; std::map FPConstantMap; public: CWriter(std::ostream &o) : Out(o) {} void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); AU.addRequired(); } - virtual bool run(Module &M) { - // Initialize - TheModule = &M; - FUT = &getAnalysis(); + virtual const char *getPassName() const { return "C backend"; } - // Ensure that all structure types have names... - bool Changed = nameAllUsedStructureTypes(M); - Mang = new Mangler(M); + bool doInitialization(Module &M); + bool run(Module &M) { + doInitialization(M); - // Run... - printModule(&M); + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isExternal()) + printFunction(*I); // Free memory... delete Mang; TypeNames.clear(); MangledGlobals.clear(); - return false; + return true; } std::ostream &printType(std::ostream &Out, const Type *Ty, @@ -85,7 +84,7 @@ namespace { void printContainedStructs(const Type *Ty, std::set &); void printFunctionSignature(const Function *F, bool Prototype); - void printFunction(Function *); + void printFunction(Function &); void printConstant(Constant *CPV); void printConstantArray(ConstantArray *CPA); @@ -604,42 +603,27 @@ static void generateCompilerSpecificCode(std::ostream& Out) { << "#endif\n\n"; } -// generateProcessorSpecificCode - This is where we add conditional compilation -// directives to cater to specific processors as need be. -// -static void generateProcessorSpecificCode(std::ostream& Out) { - // According to ANSI C, longjmp'ing to a setjmp could invalidate any - // non-volatile variable in the scope of the setjmp. For now, we are not - // doing analysis to determine which variables need to be marked volatile, so - // we just mark them all. - // - // HOWEVER, many targets implement setjmp by saving and restoring the register - // file, so they DON'T need variables to be marked volatile, and this is a - // HUGE pessimization for them. For this reason, on known-good processors, we - // do not emit volatile qualifiers. - Out << "#if defined(__386__) || defined(__i386__) || \\\n" - << " defined(i386) || defined(WIN32)\n" - << "/* setjmp does not require variables to be marked volatile */" - << "#define VOLATILE_FOR_SETJMP\n" - << "#else\n" - << "#define VOLATILE_FOR_SETJMP volatile\n" - << "#endif\n\n"; -} - +bool CWriter::doInitialization(Module &M) { + // Initialize + TheModule = &M; + FUT = &getAnalysis(); + + // Ensure that all structure types have names... + bool Changed = nameAllUsedStructureTypes(M); + Mang = new Mangler(M); -void CWriter::printModule(Module *M) { // Calculate which global values have names that will collide when we throw // away type information. { // Scope to delete the FoundNames set when we are done with it... std::set FoundNames; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (I->hasName()) // If the global has a name... if (FoundNames.count(I->getName())) // And the name is already used MangledGlobals.insert(I); // Mangle the name else FoundNames.insert(I->getName()); // Otherwise, keep track of name - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) if (I->hasName()) // If the global has a name... if (FoundNames.count(I->getName())) // And the name is already used MangledGlobals.insert(I); // Mangle the name @@ -652,7 +636,6 @@ void CWriter::printModule(Module *M) { Out << "#include \n"; // Varargs support Out << "#include \n"; // Unwind support generateCompilerSpecificCode(Out); - generateProcessorSpecificCode(Out); // Provide a definition for `bool' if not compiling with a C++ compiler. Out << "\n" @@ -662,11 +645,6 @@ void CWriter::printModule(Module *M) { << "typedef unsigned long long ConstantDoubleTy;\n" << "typedef unsigned int ConstantFloatTy;\n" - << "\n\n/* Support for the invoke instruction */\n" - << "extern struct __llvm_jmpbuf_list_t {\n" - << " jmp_buf buf; struct __llvm_jmpbuf_list_t *next;\n" - << "} *__llvm_jmpbuf_list;\n" - << "\n\n/* Global Declarations */\n"; // First output all the declarations for the program, because C requires @@ -674,12 +652,12 @@ void CWriter::printModule(Module *M) { // // Loop over the symbol table, emitting all named constants... - printSymbolTable(M->getSymbolTable()); + printSymbolTable(M.getSymbolTable()); // Global variable declarations... - if (!M->gempty()) { + if (!M.gempty()) { Out << "\n/* External Global Variable Declarations */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) { + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) { if (I->hasExternalLinkage()) { Out << "extern "; printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); @@ -689,15 +667,16 @@ void CWriter::printModule(Module *M) { } // Function declarations - if (!M->empty()) { + if (!M.empty()) { Out << "\n/* Function Declarations */\n"; needsMalloc = true; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { // If the function is external and the name collides don't print it. // Sometimes the bytecode likes to have multiple "declarations" for // external functions if ((I->hasInternalLinkage() || !MangledGlobals.count(I)) && - !I->getIntrinsicID()) { + !I->getIntrinsicID() && + I->getName() != "setjmp" && I->getName() != "longjmp") { printFunctionSignature(I, true); if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; Out << ";\n"; @@ -712,9 +691,9 @@ void CWriter::printModule(Module *M) { } // Output the global variable declarations - if (!M->gempty()) { + if (!M.gempty()) { Out << "\n\n/* Global Variable Declarations */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) if (!I->isExternal()) { Out << "extern "; printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); @@ -728,9 +707,9 @@ void CWriter::printModule(Module *M) { } // Output the global variable definitions and contents... - if (!M->gempty()) { + if (!M.gempty()) { Out << "\n\n/* Global Variable Definitions and Initialization */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) if (!I->isExternal()) { if (I->hasInternalLinkage()) Out << "static "; @@ -755,28 +734,14 @@ void CWriter::printModule(Module *M) { } // Output all floating point constants that cannot be printed accurately... - printFloatingPointConstants(*M); + printFloatingPointConstants(M); - // Output all of the functions... - emittedInvoke = false; - if (!M->empty()) { + if (!M.empty()) Out << "\n\n/* Function Bodies */\n"; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - printFunction(I); - } - - // If the program included an invoke instruction, we need to output the - // support code for it here! - if (emittedInvoke) { - Out << "\n/* More support for the invoke instruction */\n" - << "struct __llvm_jmpbuf_list_t *__llvm_jmpbuf_list " - << "__attribute__((common)) = 0;\n"; - } - - // Done with global FP constants - FPConstantMap.clear(); + return false; } + /// Output all floating point constants that cannot be printed accurately... void CWriter::printFloatingPointConstants(Module &M) { union { @@ -963,36 +928,23 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { printType(Out, F->getReturnType(), FunctionInnards.str()); } -void CWriter::printFunction(Function *F) { - if (F->isExternal()) return; - - printFunctionSignature(F, false); +void CWriter::printFunction(Function &F) { + printFunctionSignature(&F, false); Out << " {\n"; - // Determine whether or not the function contains any invoke instructions. - bool HasInvoke = false; - for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) - if (isa(I->getTerminator())) { - HasInvoke = true; - break; - } - // print local variable information for the function - for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) + for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) if (const AllocaInst *AI = isDirectAlloca(*I)) { Out << " "; - if (HasInvoke) Out << "VOLATILE_FOR_SETJMP "; printType(Out, AI->getAllocatedType(), Mang->getValueName(AI)); Out << "; /* Address exposed local */\n"; } else if ((*I)->getType() != Type::VoidTy && !isInlinableInst(**I)) { Out << " "; - if (HasInvoke) Out << "VOLATILE_FOR_SETJMP "; printType(Out, (*I)->getType(), Mang->getValueName(*I)); Out << ";\n"; if (isa(*I)) { // Print out PHI node temporaries as well... Out << " "; - if (HasInvoke) Out << "VOLATILE_FOR_SETJMP "; printType(Out, (*I)->getType(), Mang->getValueName(*I)+"__PHI_TEMPORARY"); Out << ";\n"; @@ -1002,7 +954,7 @@ void CWriter::printFunction(Function *F) { Out << "\n"; // print the basic blocks - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { BasicBlock *Prev = BB->getPrev(); // Don't print the label for the basic block if there are no uses, or if the @@ -1080,43 +1032,12 @@ void CWriter::visitSwitchInst(SwitchInst &SI) { } void CWriter::visitInvokeInst(InvokeInst &II) { - Out << " {\n" - << " struct __llvm_jmpbuf_list_t Entry;\n" - << " Entry.next = __llvm_jmpbuf_list;\n" - << " if (setjmp(Entry.buf)) {\n" - << " __llvm_jmpbuf_list = Entry.next;\n"; - printBranchToBlock(II.getParent(), II.getUnwindDest(), 4); - Out << " }\n" - << " __llvm_jmpbuf_list = &Entry;\n" - << " "; - - if (II.getType() != Type::VoidTy) outputLValue(&II); - visitCallSite(&II); - Out << ";\n" - << " __llvm_jmpbuf_list = Entry.next;\n" - << " }\n"; - printBranchToBlock(II.getParent(), II.getNormalDest(), 0); - emittedInvoke = true; + assert(0 && "Lowerinvoke pass didn't work!"); } void CWriter::visitUnwindInst(UnwindInst &I) { - // The unwind instructions causes a control flow transfer out of the current - // function, unwinding the stack until a caller who used the invoke - // instruction is found. In this context, we code generated the invoke - // instruction to add an entry to the top of the jmpbuf_list. Thus, here we - // just have to longjmp to the specified handler. - Out << " if (__llvm_jmpbuf_list == 0) { /* unwind */\n" - << "#ifdef _LP64\n" - << " extern signed long long write();\n" - << "#else\n" - << " extern write();\n" - << "#endif\n" - << " ((void (*)(int, void*, unsigned))write)(2,\n" - << " \"throw found with no handler!\\n\", 31); abort();\n" - << " }\n" - << " longjmp(__llvm_jmpbuf_list->buf, 1);\n"; - emittedInvoke = true; + assert(0 && "Lowerinvoke pass didn't work!"); } bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) { @@ -1473,4 +1394,8 @@ void CWriter::visitVAArgInst(VAArgInst &I) { // External Interface declaration //===----------------------------------------------------------------------===// -Pass *llvm::createWriteToCPass(std::ostream &o) { return new CWriter(o); } +void llvm::AddPassesToWriteC(PassManager &PM, std::ostream &o) { + PM.add(createLowerInvokePass()); + //PM.add(createLowerAllocationsPass()); + PM.add(new CWriter(o)); +} diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 73f43416219..cd24e2765d7 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -18,10 +18,12 @@ #include "llvm/Module.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" +#include "llvm/PassManager.h" #include "llvm/SymbolTable.h" #include "llvm/Intrinsics.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/ConstantsScanner.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/InstVisitor.h" @@ -40,34 +42,31 @@ namespace { std::map TypeNames; std::set MangledGlobals; - bool needsMalloc, emittedInvoke; + bool needsMalloc; std::map FPConstantMap; public: CWriter(std::ostream &o) : Out(o) {} void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); AU.addRequired(); } - virtual bool run(Module &M) { - // Initialize - TheModule = &M; - FUT = &getAnalysis(); + virtual const char *getPassName() const { return "C backend"; } - // Ensure that all structure types have names... - bool Changed = nameAllUsedStructureTypes(M); - Mang = new Mangler(M); + bool doInitialization(Module &M); + bool run(Module &M) { + doInitialization(M); - // Run... - printModule(&M); + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isExternal()) + printFunction(*I); // Free memory... delete Mang; TypeNames.clear(); MangledGlobals.clear(); - return false; + return true; } std::ostream &printType(std::ostream &Out, const Type *Ty, @@ -85,7 +84,7 @@ namespace { void printContainedStructs(const Type *Ty, std::set &); void printFunctionSignature(const Function *F, bool Prototype); - void printFunction(Function *); + void printFunction(Function &); void printConstant(Constant *CPV); void printConstantArray(ConstantArray *CPA); @@ -604,42 +603,27 @@ static void generateCompilerSpecificCode(std::ostream& Out) { << "#endif\n\n"; } -// generateProcessorSpecificCode - This is where we add conditional compilation -// directives to cater to specific processors as need be. -// -static void generateProcessorSpecificCode(std::ostream& Out) { - // According to ANSI C, longjmp'ing to a setjmp could invalidate any - // non-volatile variable in the scope of the setjmp. For now, we are not - // doing analysis to determine which variables need to be marked volatile, so - // we just mark them all. - // - // HOWEVER, many targets implement setjmp by saving and restoring the register - // file, so they DON'T need variables to be marked volatile, and this is a - // HUGE pessimization for them. For this reason, on known-good processors, we - // do not emit volatile qualifiers. - Out << "#if defined(__386__) || defined(__i386__) || \\\n" - << " defined(i386) || defined(WIN32)\n" - << "/* setjmp does not require variables to be marked volatile */" - << "#define VOLATILE_FOR_SETJMP\n" - << "#else\n" - << "#define VOLATILE_FOR_SETJMP volatile\n" - << "#endif\n\n"; -} - +bool CWriter::doInitialization(Module &M) { + // Initialize + TheModule = &M; + FUT = &getAnalysis(); + + // Ensure that all structure types have names... + bool Changed = nameAllUsedStructureTypes(M); + Mang = new Mangler(M); -void CWriter::printModule(Module *M) { // Calculate which global values have names that will collide when we throw // away type information. { // Scope to delete the FoundNames set when we are done with it... std::set FoundNames; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (I->hasName()) // If the global has a name... if (FoundNames.count(I->getName())) // And the name is already used MangledGlobals.insert(I); // Mangle the name else FoundNames.insert(I->getName()); // Otherwise, keep track of name - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) if (I->hasName()) // If the global has a name... if (FoundNames.count(I->getName())) // And the name is already used MangledGlobals.insert(I); // Mangle the name @@ -652,7 +636,6 @@ void CWriter::printModule(Module *M) { Out << "#include \n"; // Varargs support Out << "#include \n"; // Unwind support generateCompilerSpecificCode(Out); - generateProcessorSpecificCode(Out); // Provide a definition for `bool' if not compiling with a C++ compiler. Out << "\n" @@ -662,11 +645,6 @@ void CWriter::printModule(Module *M) { << "typedef unsigned long long ConstantDoubleTy;\n" << "typedef unsigned int ConstantFloatTy;\n" - << "\n\n/* Support for the invoke instruction */\n" - << "extern struct __llvm_jmpbuf_list_t {\n" - << " jmp_buf buf; struct __llvm_jmpbuf_list_t *next;\n" - << "} *__llvm_jmpbuf_list;\n" - << "\n\n/* Global Declarations */\n"; // First output all the declarations for the program, because C requires @@ -674,12 +652,12 @@ void CWriter::printModule(Module *M) { // // Loop over the symbol table, emitting all named constants... - printSymbolTable(M->getSymbolTable()); + printSymbolTable(M.getSymbolTable()); // Global variable declarations... - if (!M->gempty()) { + if (!M.gempty()) { Out << "\n/* External Global Variable Declarations */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) { + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) { if (I->hasExternalLinkage()) { Out << "extern "; printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); @@ -689,15 +667,16 @@ void CWriter::printModule(Module *M) { } // Function declarations - if (!M->empty()) { + if (!M.empty()) { Out << "\n/* Function Declarations */\n"; needsMalloc = true; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { // If the function is external and the name collides don't print it. // Sometimes the bytecode likes to have multiple "declarations" for // external functions if ((I->hasInternalLinkage() || !MangledGlobals.count(I)) && - !I->getIntrinsicID()) { + !I->getIntrinsicID() && + I->getName() != "setjmp" && I->getName() != "longjmp") { printFunctionSignature(I, true); if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; Out << ";\n"; @@ -712,9 +691,9 @@ void CWriter::printModule(Module *M) { } // Output the global variable declarations - if (!M->gempty()) { + if (!M.gempty()) { Out << "\n\n/* Global Variable Declarations */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) if (!I->isExternal()) { Out << "extern "; printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); @@ -728,9 +707,9 @@ void CWriter::printModule(Module *M) { } // Output the global variable definitions and contents... - if (!M->gempty()) { + if (!M.gempty()) { Out << "\n\n/* Global Variable Definitions and Initialization */\n"; - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) if (!I->isExternal()) { if (I->hasInternalLinkage()) Out << "static "; @@ -755,28 +734,14 @@ void CWriter::printModule(Module *M) { } // Output all floating point constants that cannot be printed accurately... - printFloatingPointConstants(*M); + printFloatingPointConstants(M); - // Output all of the functions... - emittedInvoke = false; - if (!M->empty()) { + if (!M.empty()) Out << "\n\n/* Function Bodies */\n"; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - printFunction(I); - } - - // If the program included an invoke instruction, we need to output the - // support code for it here! - if (emittedInvoke) { - Out << "\n/* More support for the invoke instruction */\n" - << "struct __llvm_jmpbuf_list_t *__llvm_jmpbuf_list " - << "__attribute__((common)) = 0;\n"; - } - - // Done with global FP constants - FPConstantMap.clear(); + return false; } + /// Output all floating point constants that cannot be printed accurately... void CWriter::printFloatingPointConstants(Module &M) { union { @@ -963,36 +928,23 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) { printType(Out, F->getReturnType(), FunctionInnards.str()); } -void CWriter::printFunction(Function *F) { - if (F->isExternal()) return; - - printFunctionSignature(F, false); +void CWriter::printFunction(Function &F) { + printFunctionSignature(&F, false); Out << " {\n"; - // Determine whether or not the function contains any invoke instructions. - bool HasInvoke = false; - for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) - if (isa(I->getTerminator())) { - HasInvoke = true; - break; - } - // print local variable information for the function - for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) + for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) if (const AllocaInst *AI = isDirectAlloca(*I)) { Out << " "; - if (HasInvoke) Out << "VOLATILE_FOR_SETJMP "; printType(Out, AI->getAllocatedType(), Mang->getValueName(AI)); Out << "; /* Address exposed local */\n"; } else if ((*I)->getType() != Type::VoidTy && !isInlinableInst(**I)) { Out << " "; - if (HasInvoke) Out << "VOLATILE_FOR_SETJMP "; printType(Out, (*I)->getType(), Mang->getValueName(*I)); Out << ";\n"; if (isa(*I)) { // Print out PHI node temporaries as well... Out << " "; - if (HasInvoke) Out << "VOLATILE_FOR_SETJMP "; printType(Out, (*I)->getType(), Mang->getValueName(*I)+"__PHI_TEMPORARY"); Out << ";\n"; @@ -1002,7 +954,7 @@ void CWriter::printFunction(Function *F) { Out << "\n"; // print the basic blocks - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { BasicBlock *Prev = BB->getPrev(); // Don't print the label for the basic block if there are no uses, or if the @@ -1080,43 +1032,12 @@ void CWriter::visitSwitchInst(SwitchInst &SI) { } void CWriter::visitInvokeInst(InvokeInst &II) { - Out << " {\n" - << " struct __llvm_jmpbuf_list_t Entry;\n" - << " Entry.next = __llvm_jmpbuf_list;\n" - << " if (setjmp(Entry.buf)) {\n" - << " __llvm_jmpbuf_list = Entry.next;\n"; - printBranchToBlock(II.getParent(), II.getUnwindDest(), 4); - Out << " }\n" - << " __llvm_jmpbuf_list = &Entry;\n" - << " "; - - if (II.getType() != Type::VoidTy) outputLValue(&II); - visitCallSite(&II); - Out << ";\n" - << " __llvm_jmpbuf_list = Entry.next;\n" - << " }\n"; - printBranchToBlock(II.getParent(), II.getNormalDest(), 0); - emittedInvoke = true; + assert(0 && "Lowerinvoke pass didn't work!"); } void CWriter::visitUnwindInst(UnwindInst &I) { - // The unwind instructions causes a control flow transfer out of the current - // function, unwinding the stack until a caller who used the invoke - // instruction is found. In this context, we code generated the invoke - // instruction to add an entry to the top of the jmpbuf_list. Thus, here we - // just have to longjmp to the specified handler. - Out << " if (__llvm_jmpbuf_list == 0) { /* unwind */\n" - << "#ifdef _LP64\n" - << " extern signed long long write();\n" - << "#else\n" - << " extern write();\n" - << "#endif\n" - << " ((void (*)(int, void*, unsigned))write)(2,\n" - << " \"throw found with no handler!\\n\", 31); abort();\n" - << " }\n" - << " longjmp(__llvm_jmpbuf_list->buf, 1);\n"; - emittedInvoke = true; + assert(0 && "Lowerinvoke pass didn't work!"); } bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To) { @@ -1473,4 +1394,8 @@ void CWriter::visitVAArgInst(VAArgInst &I) { // External Interface declaration //===----------------------------------------------------------------------===// -Pass *llvm::createWriteToCPass(std::ostream &o) { return new CWriter(o); } +void llvm::AddPassesToWriteC(PassManager &PM, std::ostream &o) { + PM.add(createLowerInvokePass()); + //PM.add(createLowerAllocationsPass()); + PM.add(new CWriter(o)); +}