aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/LibCallSemantics.cpp
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-04-01 18:49:24 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-04-01 18:49:26 +0000
commit3fa16bd6062e23bcdb82ed4dd965674792e6b761 (patch)
tree9348fc507292f7e8715d22d64ce5a32131b4f875 /lib/Analysis/LibCallSemantics.cpp
parentbeed47390a60f6f0c77532b3d3f76bb47ef49423 (diff)
parentebe69fe11e48d322045d5949c83283927a0d790b (diff)
downloadexternal_llvm-3fa16bd6062e23bcdb82ed4dd965674792e6b761.zip
external_llvm-3fa16bd6062e23bcdb82ed4dd965674792e6b761.tar.gz
external_llvm-3fa16bd6062e23bcdb82ed4dd965674792e6b761.tar.bz2
Merge "Update aosp/master LLVM for rebase to r230699."
Diffstat (limited to 'lib/Analysis/LibCallSemantics.cpp')
-rw-r--r--lib/Analysis/LibCallSemantics.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/Analysis/LibCallSemantics.cpp b/lib/Analysis/LibCallSemantics.cpp
index 23639e7..cf752dd 100644
--- a/lib/Analysis/LibCallSemantics.cpp
+++ b/lib/Analysis/LibCallSemantics.cpp
@@ -15,6 +15,7 @@
#include "llvm/Analysis/LibCallSemantics.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Function.h"
using namespace llvm;
@@ -61,3 +62,41 @@ LibCallInfo::getFunctionInfo(const Function *F) const {
return Map->lookup(F->getName());
}
+/// See if the given exception handling personality function is one that we
+/// understand. If so, return a description of it; otherwise return Unknown.
+EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
+ const Function *F = dyn_cast<Function>(Pers->stripPointerCasts());
+ if (!F)
+ return EHPersonality::Unknown;
+ return StringSwitch<EHPersonality>(F->getName())
+ .Case("__gnat_eh_personality", EHPersonality::GNU_Ada)
+ .Case("__gxx_personality_v0", EHPersonality::GNU_CXX)
+ .Case("__gcc_personality_v0", EHPersonality::GNU_C)
+ .Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
+ .Case("__except_handler3", EHPersonality::MSVC_X86SEH)
+ .Case("__except_handler4", EHPersonality::MSVC_X86SEH)
+ .Case("__C_specific_handler", EHPersonality::MSVC_Win64SEH)
+ .Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX)
+ .Default(EHPersonality::Unknown);
+}
+
+bool llvm::isAsynchronousEHPersonality(EHPersonality Pers) {
+ // The two SEH personality functions can catch asynch exceptions. We assume
+ // unknown personalities don't catch asynch exceptions.
+ switch (Pers) {
+ case EHPersonality::MSVC_X86SEH:
+ case EHPersonality::MSVC_Win64SEH:
+ return true;
+ default: return false;
+ }
+ llvm_unreachable("invalid enum");
+}
+
+bool llvm::canSimplifyInvokeNoUnwind(const InvokeInst *II) {
+ const LandingPadInst *LP = II->getLandingPadInst();
+ EHPersonality Personality = classifyEHPersonality(LP->getPersonalityFn());
+ // We can't simplify any invokes to nounwind functions if the personality
+ // function wants to catch asynch exceptions. The nounwind attribute only
+ // implies that the function does not throw synchronous exceptions.
+ return !isAsynchronousEHPersonality(Personality);
+}