diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index eb804c1df1b..3132999dde4 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -22,7 +22,7 @@ #include "llvm/IR/Instructions.h" namespace llvm { -class GlobalVariable; +class GlobalValue; class TargetLoweringBase; class TargetLowering; class TargetMachine; @@ -59,7 +59,7 @@ void ComputeValueVTs(const TargetLowering &TLI, Type *Ty, uint64_t StartingOffset = 0); /// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V. -GlobalVariable *ExtractTypeInfo(Value *V); +GlobalValue *ExtractTypeInfo(Value *V); /// hasInlineAsmMemConstraint - Return true if the inline asm instruction being /// processed uses a memory 'm' constraint. diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index 52e0121ccef..6653333a18f 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -127,7 +127,7 @@ class MachineModuleInfo : public ImmutablePass { unsigned CurCallSite; /// TypeInfos - List of C++ TypeInfo used in the current function. - std::vector TypeInfos; + std::vector TypeInfos; /// FilterIds - List of typeids encoding filters used in the current function. std::vector FilterIds; @@ -301,12 +301,12 @@ public: /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. /// void addCatchTypeInfo(MachineBasicBlock *LandingPad, - ArrayRef TyInfo); + ArrayRef TyInfo); /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. /// void addFilterTypeInfo(MachineBasicBlock *LandingPad, - ArrayRef TyInfo); + ArrayRef TyInfo); /// addCleanup - Add a cleanup action for a landing pad. /// @@ -314,7 +314,7 @@ public: /// getTypeIDFor - Return the type id for the specified typeinfo. This is /// function wide. - unsigned getTypeIDFor(const GlobalVariable *TI); + unsigned getTypeIDFor(const GlobalValue *TI); /// getFilterIDFor - Return the id of the filter encoded by TyIds. This is /// function wide. @@ -375,7 +375,7 @@ public: /// getTypeInfos - Return a reference to the C++ typeinfo for the current /// function. - const std::vector &getTypeInfos() const { + const std::vector &getTypeInfos() const { return TypeInfos; } diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp index 02036352433..9a3b7905e4a 100644 --- a/lib/CodeGen/Analysis.cpp +++ b/lib/CodeGen/Analysis.cpp @@ -109,15 +109,16 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, Type *Ty, } /// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V. -GlobalVariable *llvm::ExtractTypeInfo(Value *V) { +GlobalValue *llvm::ExtractTypeInfo(Value *V) { V = V->stripPointerCasts(); - GlobalVariable *GV = dyn_cast(V); + GlobalValue *GV = dyn_cast(V); + GlobalVariable *Var = dyn_cast(V); - if (GV && GV->getName() == "llvm.eh.catch.all.value") { - assert(GV->hasInitializer() && + if (Var && Var->getName() == "llvm.eh.catch.all.value") { + assert(Var->hasInitializer() && "The EH catch-all value must have an initializer"); - Value *Init = GV->getInitializer(); - GV = dyn_cast(Init); + Value *Init = Var->getInitializer(); + GV = dyn_cast(Init); if (!GV) V = cast(Init); } diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp index 251f5effd6b..66c6c633540 100644 --- a/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -108,7 +108,7 @@ void ARMException::endFunction(const MachineFunction *) { } void ARMException::emitTypeInfos(unsigned TTypeEncoding) { - const std::vector &TypeInfos = MMI->getTypeInfos(); + const std::vector &TypeInfos = MMI->getTypeInfos(); const std::vector &FilterIds = MMI->getFilterIds(); bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); @@ -121,9 +121,9 @@ void ARMException::emitTypeInfos(unsigned TTypeEncoding) { Entry = TypeInfos.size(); } - for (std::vector::const_reverse_iterator + for (std::vector::const_reverse_iterator I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { - const GlobalVariable *GV = *I; + const GlobalValue *GV = *I; if (VerboseAsm) Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--)); Asm->EmitTTypeReference(GV, TTypeEncoding); diff --git a/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/lib/CodeGen/AsmPrinter/EHStreamer.cpp index 73f62bfd804..58e524c8a51 100644 --- a/lib/CodeGen/AsmPrinter/EHStreamer.cpp +++ b/lib/CodeGen/AsmPrinter/EHStreamer.cpp @@ -314,7 +314,7 @@ computeCallSiteTable(SmallVectorImpl &CallSites, /// 3. Type ID table contains references to all the C++ typeinfo for all /// catches in the function. This tables is reverse indexed base 1. void EHStreamer::emitExceptionTable() { - const std::vector &TypeInfos = MMI->getTypeInfos(); + const std::vector &TypeInfos = MMI->getTypeInfos(); const std::vector &FilterIds = MMI->getFilterIds(); const std::vector &PadInfos = MMI->getLandingPads(); @@ -649,7 +649,7 @@ void EHStreamer::emitExceptionTable() { } void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) { - const std::vector &TypeInfos = MMI->getTypeInfos(); + const std::vector &TypeInfos = MMI->getTypeInfos(); const std::vector &FilterIds = MMI->getFilterIds(); bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); @@ -662,9 +662,9 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) { Entry = TypeInfos.size(); } - for (std::vector::const_reverse_iterator + for (std::vector::const_reverse_iterator I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { - const GlobalVariable *GV = *I; + const GlobalValue *GV = *I; if (VerboseAsm) Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--)); Asm->EmitTTypeReference(GV, TTypeEncoding); diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 4117b174442..eb3c0bf224d 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -427,7 +427,7 @@ void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad, /// void MachineModuleInfo:: addCatchTypeInfo(MachineBasicBlock *LandingPad, - ArrayRef TyInfo) { + ArrayRef TyInfo) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); for (unsigned N = TyInfo.size(); N; --N) LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1])); @@ -437,7 +437,7 @@ addCatchTypeInfo(MachineBasicBlock *LandingPad, /// void MachineModuleInfo:: addFilterTypeInfo(MachineBasicBlock *LandingPad, - ArrayRef TyInfo) { + ArrayRef TyInfo) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); std::vector IdsInFilter(TyInfo.size()); for (unsigned I = 0, E = TyInfo.size(); I != E; ++I) @@ -506,7 +506,7 @@ void MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym, /// getTypeIDFor - Return the type id for the specified typeinfo. This is /// function wide. -unsigned MachineModuleInfo::getTypeIDFor(const GlobalVariable *TI) { +unsigned MachineModuleInfo::getTypeIDFor(const GlobalValue *TI) { for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i) if (TypeInfos[i] == TI) return i + 1; diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index ff1cfe2d32b..86b9542f2f2 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -483,7 +483,7 @@ void llvm::AddCatchInfo(const CallInst &I, MachineModuleInfo *MMI, // Gather all the type infos for this landing pad and pass them along to // MachineModuleInfo. - std::vector TyInfo; + std::vector TyInfo; unsigned N = I.getNumArgOperands(); for (unsigned i = N - 1; i > 1; --i) { @@ -541,14 +541,14 @@ void llvm::AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI, Value *Val = I.getClause(i - 1); if (I.isCatch(i - 1)) { MMI.addCatchTypeInfo(MBB, - dyn_cast(Val->stripPointerCasts())); + dyn_cast(Val->stripPointerCasts())); } else { // Add filters in a list. Constant *CVal = cast(Val); - SmallVector FilterList; + SmallVector FilterList; for (User::op_iterator II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) - FilterList.push_back(cast((*II)->stripPointerCasts())); + FilterList.push_back(cast((*II)->stripPointerCasts())); MMI.addFilterTypeInfo(MBB, FilterList); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 4b4b90b5837..8f8627a0b11 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4847,7 +4847,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { case Intrinsic::eh_typeid_for: { // Find the type id for the given typeinfo. - GlobalVariable *GV = ExtractTypeInfo(I.getArgOperand(0)); + GlobalValue *GV = ExtractTypeInfo(I.getArgOperand(0)); unsigned TypeID = DAG.getMachineFunction().getMMI().getTypeIDFor(GV); Res = DAG.getConstant(TypeID, MVT::i32); setValue(&I, Res); diff --git a/test/CodeGen/X86/gcc_except_table_functions.ll b/test/CodeGen/X86/gcc_except_table_functions.ll new file mode 100644 index 00000000000..4a8168050e5 --- /dev/null +++ b/test/CodeGen/X86/gcc_except_table_functions.ll @@ -0,0 +1,53 @@ +; RUN: llc -mtriple x86_64-pc-linux-gnu < %s | FileCheck %s + +; This test demonstrates that it is possible to use functions for typeinfo +; instead of global variables. While __gxx_personality_v0 would never know what +; to do with them, other EH schemes such as SEH might use them. + +declare i32 @__gxx_personality_v0(...) +declare void @filt0() +declare void @filt1() +declare void @_Z1fv() +declare i32 @llvm.eh.typeid.for(i8*) + +define i32 @main() uwtable { +entry: + invoke void @_Z1fv() + to label %try.cont unwind label %lpad + +try.cont: + ret i32 0 + +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (void ()* @filt0 to i8*) + catch i8* bitcast (void ()* @filt1 to i8*) + %sel = extractvalue { i8*, i32 } %0, 1 + %id0 = call i32 @llvm.eh.typeid.for(i8* bitcast (void ()* @filt0 to i8*)) + %is_f0 = icmp eq i32 %sel, %id0 + br i1 %is_f0, label %try.cont, label %check_f1 + +check_f1: + %id1 = call i32 @llvm.eh.typeid.for(i8* bitcast (void ()* @filt1 to i8*)) + %is_f1 = icmp eq i32 %sel, %id1 + br i1 %is_f1, label %try.cont, label %eh.resume + +eh.resume: + resume { i8*, i32 } %0 +} + +; CHECK-LABEL: main: +; CHECK: .cfi_startproc +; CHECK: .cfi_personality 3, __gxx_personality_v0 +; CHECK: .cfi_lsda 3, .Lexception0 +; CHECK: .cfi_def_cfa_offset 16 +; CHECK: callq _Z1fv +; CHECK: retq +; CHECK: cmpl $2, %edx +; CHECK: je +; CHECK: cmpl $1, %edx +; CHECK: je +; CHECK: callq _Unwind_Resume +; CHECK: .cfi_endproc +; CHECK: GCC_except_table0: +; CHECK: Lexception0: