mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Allow the use of functions as typeinfo in landingpad clauses
This is one step towards supporting SEH filter functions in LLVM. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221954 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0dfb75c92a
commit
98c86d76df
@ -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.
|
||||
|
@ -127,7 +127,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
unsigned CurCallSite;
|
||||
|
||||
/// TypeInfos - List of C++ TypeInfo used in the current function.
|
||||
std::vector<const GlobalVariable *> TypeInfos;
|
||||
std::vector<const GlobalValue *> TypeInfos;
|
||||
|
||||
/// FilterIds - List of typeids encoding filters used in the current function.
|
||||
std::vector<unsigned> FilterIds;
|
||||
@ -301,12 +301,12 @@ public:
|
||||
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
|
||||
///
|
||||
void addCatchTypeInfo(MachineBasicBlock *LandingPad,
|
||||
ArrayRef<const GlobalVariable *> TyInfo);
|
||||
ArrayRef<const GlobalValue *> TyInfo);
|
||||
|
||||
/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
|
||||
///
|
||||
void addFilterTypeInfo(MachineBasicBlock *LandingPad,
|
||||
ArrayRef<const GlobalVariable *> TyInfo);
|
||||
ArrayRef<const GlobalValue *> 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<const GlobalVariable *> &getTypeInfos() const {
|
||||
const std::vector<const GlobalValue *> &getTypeInfos() const {
|
||||
return TypeInfos;
|
||||
}
|
||||
|
||||
|
@ -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<GlobalVariable>(V);
|
||||
GlobalValue *GV = dyn_cast<GlobalValue>(V);
|
||||
GlobalVariable *Var = dyn_cast<GlobalVariable>(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<GlobalVariable>(Init);
|
||||
Value *Init = Var->getInitializer();
|
||||
GV = dyn_cast<GlobalValue>(Init);
|
||||
if (!GV) V = cast<ConstantPointerNull>(Init);
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ void ARMException::endFunction(const MachineFunction *) {
|
||||
}
|
||||
|
||||
void ARMException::emitTypeInfos(unsigned TTypeEncoding) {
|
||||
const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
|
||||
bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
|
||||
@ -121,9 +121,9 @@ void ARMException::emitTypeInfos(unsigned TTypeEncoding) {
|
||||
Entry = TypeInfos.size();
|
||||
}
|
||||
|
||||
for (std::vector<const GlobalVariable *>::const_reverse_iterator
|
||||
for (std::vector<const GlobalValue *>::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);
|
||||
|
@ -314,7 +314,7 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &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<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
|
||||
|
||||
@ -649,7 +649,7 @@ void EHStreamer::emitExceptionTable() {
|
||||
}
|
||||
|
||||
void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) {
|
||||
const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
|
||||
bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
|
||||
@ -662,9 +662,9 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) {
|
||||
Entry = TypeInfos.size();
|
||||
}
|
||||
|
||||
for (std::vector<const GlobalVariable *>::const_reverse_iterator
|
||||
for (std::vector<const GlobalValue *>::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);
|
||||
|
@ -427,7 +427,7 @@ void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
|
||||
///
|
||||
void MachineModuleInfo::
|
||||
addCatchTypeInfo(MachineBasicBlock *LandingPad,
|
||||
ArrayRef<const GlobalVariable *> TyInfo) {
|
||||
ArrayRef<const GlobalValue *> 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<const GlobalVariable *> TyInfo) {
|
||||
ArrayRef<const GlobalValue *> TyInfo) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
std::vector<unsigned> 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;
|
||||
|
||||
|
@ -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<const GlobalVariable *> TyInfo;
|
||||
std::vector<const GlobalValue *> 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<GlobalVariable>(Val->stripPointerCasts()));
|
||||
dyn_cast<GlobalValue>(Val->stripPointerCasts()));
|
||||
} else {
|
||||
// Add filters in a list.
|
||||
Constant *CVal = cast<Constant>(Val);
|
||||
SmallVector<const GlobalVariable*, 4> FilterList;
|
||||
SmallVector<const GlobalValue*, 4> FilterList;
|
||||
for (User::op_iterator
|
||||
II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II)
|
||||
FilterList.push_back(cast<GlobalVariable>((*II)->stripPointerCasts()));
|
||||
FilterList.push_back(cast<GlobalValue>((*II)->stripPointerCasts()));
|
||||
|
||||
MMI.addFilterTypeInfo(MBB, FilterList);
|
||||
}
|
||||
|
@ -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);
|
||||
|
53
test/CodeGen/X86/gcc_except_table_functions.ll
Normal file
53
test/CodeGen/X86/gcc_except_table_functions.ll
Normal file
@ -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:
|
Loading…
Reference in New Issue
Block a user