Mercurial > hg > CbC > CbC_llvm
diff lib/Analysis/LibCallSemantics.cpp @ 83:60c9769439b8 LLVM3.7
LLVM 3.7
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 18 Feb 2015 14:55:36 +0900 |
parents | 54457678186b |
children | afa8332a0e37 |
line wrap: on
line diff
--- a/lib/Analysis/LibCallSemantics.cpp Mon Sep 08 22:07:30 2014 +0900 +++ b/lib/Analysis/LibCallSemantics.cpp Wed Feb 18 14:55:36 2015 +0900 @@ -15,10 +15,11 @@ #include "llvm/Analysis/LibCallSemantics.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/IR/Function.h" using namespace llvm; -/// getMap - This impl pointer in ~LibCallInfo is actually a StringMap. This +/// This impl pointer in ~LibCallInfo is actually a StringMap. This /// helper does the cast. static StringMap<const LibCallFunctionInfo*> *getMap(void *Ptr) { return static_cast<StringMap<const LibCallFunctionInfo*> *>(Ptr); @@ -38,7 +39,7 @@ } -/// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to +/// Return the LibCallFunctionInfo object corresponding to /// the specified function if we have it. If not, return null. const LibCallFunctionInfo * LibCallInfo::getFunctionInfo(const Function *F) const { @@ -61,3 +62,41 @@ 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); +}