diff options
author | Duncan Sands <baldrick@free.fr> | 2007-12-03 20:06:50 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2007-12-03 20:06:50 +0000 |
commit | a3355ffb3d30d19d226bbb75707991c60f236e37 (patch) | |
tree | 926575d8f1c3a0104fa7ea7236dd1842120e29cd /lib/VMCore | |
parent | 4cf4b69330f0b2a3ba325bcdb1ff41847c022260 (diff) | |
download | external_llvm-a3355ffb3d30d19d226bbb75707991c60f236e37.zip external_llvm-a3355ffb3d30d19d226bbb75707991c60f236e37.tar.gz external_llvm-a3355ffb3d30d19d226bbb75707991c60f236e37.tar.bz2 |
Rather than having special rules like "intrinsics cannot
throw exceptions", just mark intrinsics with the nounwind
attribute. Likewise, mark intrinsics as readnone/readonly
and get rid of special aliasing logic (which didn't use
anything more than this anyway).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44544 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/AutoUpgrade.cpp | 13 | ||||
-rw-r--r-- | lib/VMCore/Function.cpp | 33 | ||||
-rw-r--r-- | lib/VMCore/Instruction.cpp | 19 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 13 | ||||
-rw-r--r-- | lib/VMCore/Mangler.cpp | 2 |
5 files changed, 57 insertions, 23 deletions
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index 40c431c..311941f 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -20,7 +20,7 @@ using namespace llvm; -Function* llvm::UpgradeIntrinsicFunction(Function *F) { +static Function* UpgradeIntrinsicFunction1(Function *F) { assert(F && "Illegal to upgrade a non-existent Function."); // Get the Function's name. @@ -119,6 +119,17 @@ Function* llvm::UpgradeIntrinsicFunction(Function *F) { return 0; } +Function* llvm::UpgradeIntrinsicFunction(Function *F) { + Function *Upgraded = UpgradeIntrinsicFunction1(F); + + // Upgrade intrinsic attributes. This does not change the function. + if (Upgraded) + F = Upgraded; + if (unsigned id = F->getIntrinsicID(true)) + F->setParamAttrs(Intrinsic::getParamAttrs((Intrinsic::ID)id)); + return Upgraded; +} + // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the // upgraded intrinsic. All argument and return casting must be provided in // order to seamlessly integrate with existing context. diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 3794955..04db3aa 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "SymbolTableListTraitsImpl.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -435,12 +436,36 @@ const FunctionType *Intrinsic::getType(ID id, const Type **Tys, return FunctionType::get(ResultTy, ArgTys, IsVarArg); } +const ParamAttrsList *Intrinsic::getParamAttrs(ID id) { + static const ParamAttrsList *IntrinsicAttributes[Intrinsic::num_intrinsics]; + + if (IntrinsicAttributes[id]) + return IntrinsicAttributes[id]; + + ParamAttrsVector Attrs; + uint16_t Attr = ParamAttr::None; + +#define GET_INTRINSIC_ATTRIBUTES +#include "llvm/Intrinsics.gen" +#undef GET_INTRINSIC_ATTRIBUTES + + // Intrinsics cannot throw exceptions. + Attr |= ParamAttr::NoUnwind; + + Attrs.push_back(ParamAttrsWithIndex::get(0, Attr)); + IntrinsicAttributes[id] = ParamAttrsList::get(Attrs); + return IntrinsicAttributes[id]; +} + Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, unsigned numTys) { -// There can never be multiple globals with the same name of different types, -// because intrinsics must be a specific type. - return cast<Function>(M->getOrInsertFunction(getName(id, Tys, numTys), - getType(id, Tys, numTys))); + // There can never be multiple globals with the same name of different types, + // because intrinsics must be a specific type. + Function *F = + cast<Function>(M->getOrInsertFunction(getName(id, Tys, numTys), + getType(id, Tys, numTys))); + F->setParamAttrs(getParamAttrs(id)); + return F; } Value *IntrinsicInst::StripPointerCasts(Value *Ptr) { diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index a368753..9b20885 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -13,8 +13,8 @@ #include "llvm/Type.h" #include "llvm/Instructions.h" -#include "llvm/IntrinsicInst.h" #include "llvm/Function.h" +#include "llvm/Support/CallSite.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; @@ -197,31 +197,18 @@ bool Instruction::isSameOperationAs(Instruction *I) const { return true; } -// IntrinsicOnlyReadsMemory - Return true if the specified intrinsic doesn't -// have any side-effects or if it only reads memory. -static bool IntrinsicOnlyReadsMemory(unsigned IntrinsicID) { -#define GET_SIDE_EFFECT_INFO -#include "llvm/Intrinsics.gen" -#undef GET_SIDE_EFFECT_INFO - return false; -} - /// mayWriteToMemory - Return true if this instruction may modify memory. /// bool Instruction::mayWriteToMemory() const { switch (getOpcode()) { default: return false; case Instruction::Free: - case Instruction::Store: case Instruction::Invoke: + case Instruction::Store: case Instruction::VAArg: return true; case Instruction::Call: - if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(this)) { - // If the intrinsic doesn't write memory, it is safe. - return !IntrinsicOnlyReadsMemory(II->getIntrinsicID()); - } - return true; + return !cast<CallInst>(this)->onlyReadsMemory(); case Instruction::Load: return cast<LoadInst>(this)->isVolatile(); } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 7ad588c..0df0466 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -53,7 +53,18 @@ bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const { else return cast<InvokeInst>(I)->paramHasAttr(i, attr); } - +bool CallSite::doesNotAccessMemory() const { + if (CallInst *CI = dyn_cast<CallInst>(I)) + return CI->doesNotAccessMemory(); + else + return cast<InvokeInst>(I)->doesNotAccessMemory(); +} +bool CallSite::onlyReadsMemory() const { + if (CallInst *CI = dyn_cast<CallInst>(I)) + return CI->onlyReadsMemory(); + else + return cast<InvokeInst>(I)->onlyReadsMemory(); +} diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp index 8b8ba59..8689c86 100644 --- a/lib/VMCore/Mangler.cpp +++ b/lib/VMCore/Mangler.cpp @@ -135,7 +135,7 @@ std::string Mangler::getValueName(const GlobalValue *GV, const char * Suffix) { // Name mangling occurs as follows: // - If V is an intrinsic function, do not change name at all // - Otherwise, mangling occurs if global collides with existing name. - if (isa<Function>(GV) && cast<Function>(GV)->getIntrinsicID()) { + if (isa<Function>(GV) && cast<Function>(GV)->isIntrinsic()) { Name = GV->getName(); // Is an intrinsic function } else if (!GV->hasName()) { // Must mangle the global into a unique ID. |