From 9bda5f52bd347d028efa33ab057ff8b61341f920 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 28 Jun 2003 17:53:05 +0000 Subject: [PATCH] Add support for the Invoke instruction! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6934 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CBackend/CBackend.cpp | 57 +++++++++++++++++++++++++++----- lib/Target/CBackend/Writer.cpp | 57 +++++++++++++++++++++++++++----- 2 files changed, 96 insertions(+), 18 deletions(-) diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index ed4e430a1ca..57a2b15563c 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -17,6 +17,7 @@ #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/InstIterator.h" +#include "llvm/Support/CallSite.h" #include "Support/StringExtras.h" #include "Support/STLExtras.h" #include @@ -30,7 +31,7 @@ namespace { const Module *TheModule; std::map TypeNames; std::set MangledGlobals; - bool needsMalloc; + bool needsMalloc, emittedInvoke; std::map FPConstantMap; public: @@ -117,12 +118,14 @@ namespace { void visitReturnInst(ReturnInst &I); void visitBranchInst(BranchInst &I); void visitSwitchInst(SwitchInst &I); + void visitInvokeInst(InvokeInst &I); void visitPHINode(PHINode &I); void visitBinaryOperator(Instruction &I); void visitCastInst (CastInst &I); void visitCallInst (CallInst &I); + void visitCallSite (CallSite CS); void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); } void visitMallocInst(MallocInst &I); @@ -589,7 +592,7 @@ static void generateCompilerSpecificCode(std::ostream& Out) { // We output GCC specific attributes to preserve 'linkonce'ness on globals. // If we aren't being compiled with GCC, just drop these attributes. - Out << "#ifndef __GNUC__\n" + Out << "#ifndef __GNUC__ /* Can only support \"linkonce\" vars with GCC */\n" << "#define __attribute__(X)\n" << "#endif\n"; } @@ -628,6 +631,11 @@ 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 @@ -703,11 +711,20 @@ void CWriter::printModule(Module *M) { } // Output all of the functions... + emittedInvoke = false; 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"; + } } @@ -982,6 +999,24 @@ void CWriter::visitSwitchInst(SwitchInst &SI) { Out << " }\n"; } +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.getExceptionalDest(), 4); + Out << " }\n" + << " __llvm_jmpbuf_list = &Entry;\n" + << " "; + visitCallSite(&II); + Out << ";\n" + << " __llvm_jmpbuf_list = Entry.next;\n" + << " }\n"; + printBranchToBlock(II.getParent(), II.getNormalDest(), 0); + emittedInvoke = true; +} + static bool isGotoCodeNeccessary(BasicBlock *From, BasicBlock *To) { // If PHI nodes need copies, we need the copy code... @@ -994,7 +1029,7 @@ static bool isGotoCodeNeccessary(BasicBlock *From, BasicBlock *To) { } void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ, - unsigned Indent) { + unsigned Indent) { for (BasicBlock::iterator I = Succ->begin(); PHINode *PN = dyn_cast(I); ++I) { // now we have to do the printing @@ -1156,20 +1191,24 @@ void CWriter::visitCallInst(CallInst &I) { return; } } + visitCallSite(&I); +} - const PointerType *PTy = cast(I.getCalledValue()->getType()); +void CWriter::visitCallSite(CallSite CS) { + const PointerType *PTy = cast(CS.getCalledValue()->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - writeOperand(I.getOperand(0)); + writeOperand(CS.getCalledValue()); Out << "("; - if (I.getNumOperands() > 1) { - writeOperand(I.getOperand(1)); + if (CS.arg_begin() != CS.arg_end()) { + CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); + writeOperand(*AI); - for (unsigned op = 2, Eop = I.getNumOperands(); op != Eop; ++op) { + for (++AI; AI != AE; ++AI) { Out << ", "; - writeOperand(I.getOperand(op)); + writeOperand(*AI); } } Out << ")"; diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index ed4e430a1ca..57a2b15563c 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -17,6 +17,7 @@ #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/InstIterator.h" +#include "llvm/Support/CallSite.h" #include "Support/StringExtras.h" #include "Support/STLExtras.h" #include @@ -30,7 +31,7 @@ namespace { const Module *TheModule; std::map TypeNames; std::set MangledGlobals; - bool needsMalloc; + bool needsMalloc, emittedInvoke; std::map FPConstantMap; public: @@ -117,12 +118,14 @@ namespace { void visitReturnInst(ReturnInst &I); void visitBranchInst(BranchInst &I); void visitSwitchInst(SwitchInst &I); + void visitInvokeInst(InvokeInst &I); void visitPHINode(PHINode &I); void visitBinaryOperator(Instruction &I); void visitCastInst (CastInst &I); void visitCallInst (CallInst &I); + void visitCallSite (CallSite CS); void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); } void visitMallocInst(MallocInst &I); @@ -589,7 +592,7 @@ static void generateCompilerSpecificCode(std::ostream& Out) { // We output GCC specific attributes to preserve 'linkonce'ness on globals. // If we aren't being compiled with GCC, just drop these attributes. - Out << "#ifndef __GNUC__\n" + Out << "#ifndef __GNUC__ /* Can only support \"linkonce\" vars with GCC */\n" << "#define __attribute__(X)\n" << "#endif\n"; } @@ -628,6 +631,11 @@ 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 @@ -703,11 +711,20 @@ void CWriter::printModule(Module *M) { } // Output all of the functions... + emittedInvoke = false; 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"; + } } @@ -982,6 +999,24 @@ void CWriter::visitSwitchInst(SwitchInst &SI) { Out << " }\n"; } +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.getExceptionalDest(), 4); + Out << " }\n" + << " __llvm_jmpbuf_list = &Entry;\n" + << " "; + visitCallSite(&II); + Out << ";\n" + << " __llvm_jmpbuf_list = Entry.next;\n" + << " }\n"; + printBranchToBlock(II.getParent(), II.getNormalDest(), 0); + emittedInvoke = true; +} + static bool isGotoCodeNeccessary(BasicBlock *From, BasicBlock *To) { // If PHI nodes need copies, we need the copy code... @@ -994,7 +1029,7 @@ static bool isGotoCodeNeccessary(BasicBlock *From, BasicBlock *To) { } void CWriter::printBranchToBlock(BasicBlock *CurBB, BasicBlock *Succ, - unsigned Indent) { + unsigned Indent) { for (BasicBlock::iterator I = Succ->begin(); PHINode *PN = dyn_cast(I); ++I) { // now we have to do the printing @@ -1156,20 +1191,24 @@ void CWriter::visitCallInst(CallInst &I) { return; } } + visitCallSite(&I); +} - const PointerType *PTy = cast(I.getCalledValue()->getType()); +void CWriter::visitCallSite(CallSite CS) { + const PointerType *PTy = cast(CS.getCalledValue()->getType()); const FunctionType *FTy = cast(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - writeOperand(I.getOperand(0)); + writeOperand(CS.getCalledValue()); Out << "("; - if (I.getNumOperands() > 1) { - writeOperand(I.getOperand(1)); + if (CS.arg_begin() != CS.arg_end()) { + CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); + writeOperand(*AI); - for (unsigned op = 2, Eop = I.getNumOperands(); op != Eop; ++op) { + for (++AI; AI != AE; ++AI) { Out << ", "; - writeOperand(I.getOperand(op)); + writeOperand(*AI); } } Out << ")";