LLVM API Documentation

LibCallSemantics.cpp
Go to the documentation of this file.
00001 //===- LibCallSemantics.cpp - Describe library semantics ------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements interfaces that can be used to describe language
00011 // specific runtime library interfaces (e.g. libc, libm, etc) to LLVM
00012 // optimizers.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #include "llvm/Analysis/LibCallSemantics.h"
00017 #include "llvm/ADT/StringMap.h"
00018 #include "llvm/ADT/StringSwitch.h"
00019 #include "llvm/IR/Function.h"
00020 using namespace llvm;
00021 
00022 /// This impl pointer in ~LibCallInfo is actually a StringMap.  This
00023 /// helper does the cast.
00024 static StringMap<const LibCallFunctionInfo*> *getMap(void *Ptr) {
00025   return static_cast<StringMap<const LibCallFunctionInfo*> *>(Ptr);
00026 }
00027 
00028 LibCallInfo::~LibCallInfo() {
00029   delete getMap(Impl);
00030 }
00031 
00032 const LibCallLocationInfo &LibCallInfo::getLocationInfo(unsigned LocID) const {
00033   // Get location info on the first call.
00034   if (NumLocations == 0)
00035     NumLocations = getLocationInfo(Locations);
00036   
00037   assert(LocID < NumLocations && "Invalid location ID!");
00038   return Locations[LocID];
00039 }
00040 
00041 
00042 /// Return the LibCallFunctionInfo object corresponding to
00043 /// the specified function if we have it.  If not, return null.
00044 const LibCallFunctionInfo *
00045 LibCallInfo::getFunctionInfo(const Function *F) const {
00046   StringMap<const LibCallFunctionInfo*> *Map = getMap(Impl);
00047   
00048   /// If this is the first time we are querying for this info, lazily construct
00049   /// the StringMap to index it.
00050   if (!Map) {
00051     Impl = Map = new StringMap<const LibCallFunctionInfo*>();
00052     
00053     const LibCallFunctionInfo *Array = getFunctionInfoArray();
00054     if (!Array) return nullptr;
00055     
00056     // We now have the array of entries.  Populate the StringMap.
00057     for (unsigned i = 0; Array[i].Name; ++i)
00058       (*Map)[Array[i].Name] = Array+i;
00059   }
00060   
00061   // Look up this function in the string map.
00062   return Map->lookup(F->getName());
00063 }
00064 
00065 /// See if the given exception handling personality function is one that we
00066 /// understand.  If so, return a description of it; otherwise return Unknown.
00067 EHPersonality llvm::classifyEHPersonality(const Value *Pers) {
00068   const Function *F = dyn_cast<Function>(Pers->stripPointerCasts());
00069   if (!F)
00070     return EHPersonality::Unknown;
00071   return StringSwitch<EHPersonality>(F->getName())
00072     .Case("__gnat_eh_personality", EHPersonality::GNU_Ada)
00073     .Case("__gxx_personality_v0",  EHPersonality::GNU_CXX)
00074     .Case("__gcc_personality_v0",  EHPersonality::GNU_C)
00075     .Case("__objc_personality_v0", EHPersonality::GNU_ObjC)
00076     .Case("__except_handler3",     EHPersonality::MSVC_X86SEH)
00077     .Case("__except_handler4",     EHPersonality::MSVC_X86SEH)
00078     .Case("__C_specific_handler",  EHPersonality::MSVC_Win64SEH)
00079     .Case("__CxxFrameHandler3",    EHPersonality::MSVC_CXX)
00080     .Default(EHPersonality::Unknown);
00081 }
00082 
00083 bool llvm::isAsynchronousEHPersonality(EHPersonality Pers) {
00084   // The two SEH personality functions can catch asynch exceptions. We assume
00085   // unknown personalities don't catch asynch exceptions.
00086   switch (Pers) {
00087   case EHPersonality::MSVC_X86SEH:
00088   case EHPersonality::MSVC_Win64SEH:
00089     return true;
00090   default: return false;
00091   }
00092   llvm_unreachable("invalid enum");
00093 }
00094 
00095 bool llvm::canSimplifyInvokeNoUnwind(const InvokeInst *II) {
00096   const LandingPadInst *LP = II->getLandingPadInst();
00097   EHPersonality Personality = classifyEHPersonality(LP->getPersonalityFn());
00098   // We can't simplify any invokes to nounwind functions if the personality
00099   // function wants to catch asynch exceptions.  The nounwind attribute only
00100   // implies that the function does not throw synchronous exceptions.
00101   return !isAsynchronousEHPersonality(Personality);
00102 }