summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorJoerg Sonnenberger <joerg@bec.de>2015-02-23 20:23:47 +0000
committerJoerg Sonnenberger <joerg@bec.de>2015-02-23 20:23:47 +0000
commit096feeb741fe3b1c5c4b83727fdcc38ef2886a5d (patch)
treec0cd5de5fb008ae0d6beeac17afdaf99f1f0b5c9 /clang/lib/CodeGen
parent0100e6c08c84e1aba4389baa87862fb74221abc3 (diff)
downloadbcm5719-llvm-096feeb741fe3b1c5c4b83727fdcc38ef2886a5d.tar.gz
bcm5719-llvm-096feeb741fe3b1c5c4b83727fdcc38ef2886a5d.zip
Only lower __builtin_setjmp / __builtin_longjmp to
llvm.eh.sjlj.setjmp / llvm.eh.sjlj.longjmp, if the backend is known to support them outside the Exception Handling context. The default handling in LLVM codegen doesn't work and will create incorrect code. The ARM backend on the other hand will assert if the intrinsics are used. llvm-svn: 230255
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp4
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp25
-rw-r--r--clang/lib/CodeGen/TargetInfo.h7
3 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 859ad3ecd9b..3d9a83d91c9 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -859,6 +859,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
}
case Builtin::BI__builtin_setjmp: {
+ if (!getTargetHooks().hasSjLjLowering(*this))
+ break;
// Buffer is a void**.
Value *Buf = EmitScalarExpr(E->getArg(0));
@@ -881,6 +883,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(Builder.CreateCall(F, Buf));
}
case Builtin::BI__builtin_longjmp: {
+ if (!getTargetHooks().hasSjLjLowering(*this))
+ break;
Value *Buf = EmitScalarExpr(E->getArg(0));
Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 8070e311746..814a0b4eb09 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -665,6 +665,9 @@ public:
return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
}
+ bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
+ return true;
+ }
};
}
@@ -1599,6 +1602,10 @@ public:
unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
return HasAVX ? 32 : 16;
}
+
+ bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
+ return true;
+ }
};
class PS4TargetCodeGenInfo : public X86_64TargetCodeGenInfo {
@@ -3116,6 +3123,10 @@ public:
unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
return 16; // Natural alignment for Altivec vectors.
}
+
+ bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
+ return true;
+ }
};
}
@@ -3328,6 +3339,10 @@ public:
unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
return 16; // Natural alignment for Altivec and VSX vectors.
}
+
+ bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
+ return true;
+ }
};
class PPC64TargetCodeGenInfo : public DefaultTargetCodeGenInfo {
@@ -3345,6 +3360,10 @@ public:
unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
return 16; // Natural alignment for Altivec vectors.
}
+
+ bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
+ return true;
+ }
};
}
@@ -4462,6 +4481,12 @@ public:
llvm::AttributeSet::FunctionIndex,
B));
}
+
+ bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
+ return false;
+ // FIXME: backend implementation too restricted, even on Darwin.
+ // return CGF.getTarget().getTriple().isOSDarwin();
+ }
};
class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index cc469d69e39..87f13760e8e 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -225,6 +225,13 @@ public:
virtual unsigned getOpenMPSimdDefaultAlignment(QualType Type) const {
return 0;
}
+
+ /// Control whether __builtin_longjmp / __builtin_setjmp are lowered to
+ /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp or the normal library
+ /// function.
+ virtual bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const {
+ return false;
+ }
};
}
OpenPOWER on IntegriCloud