summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-12-03 20:06:50 +0000
committerDuncan Sands <baldrick@free.fr>2007-12-03 20:06:50 +0000
commita3355ffb3d30d19d226bbb75707991c60f236e37 (patch)
tree926575d8f1c3a0104fa7ea7236dd1842120e29cd
parent4cf4b69330f0b2a3ba325bcdb1ff41847c022260 (diff)
downloadllvm-a3355ffb3d30d19d226bbb75707991c60f236e37.tar.gz
llvm-a3355ffb3d30d19d226bbb75707991c60f236e37.tar.bz2
llvm-a3355ffb3d30d19d226bbb75707991c60f236e37.tar.xz
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
-rw-r--r--include/llvm/Function.h10
-rw-r--r--include/llvm/Instructions.h30
-rw-r--r--include/llvm/Intrinsics.h5
-rw-r--r--include/llvm/Support/CallSite.h6
-rw-r--r--lib/Analysis/AliasAnalysis.cpp8
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp37
-rw-r--r--lib/Analysis/IPA/CallGraph.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp24
-rw-r--r--lib/Target/CBackend/CBackend.cpp2
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp2
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp2
-rw-r--r--lib/Transforms/Scalar/LowerGC.cpp2
-rw-r--r--lib/Transforms/Scalar/SimplifyCFG.cpp2
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp8
-rw-r--r--lib/VMCore/AutoUpgrade.cpp13
-rw-r--r--lib/VMCore/Function.cpp33
-rw-r--r--lib/VMCore/Instruction.cpp19
-rw-r--r--lib/VMCore/Instructions.cpp13
-rw-r--r--lib/VMCore/Mangler.cpp2
-rw-r--r--tools/bugpoint/Miscompilation.cpp2
-rw-r--r--utils/TableGen/IntrinsicEmitter.cpp54
-rw-r--r--utils/TableGen/IntrinsicEmitter.h6
22 files changed, 136 insertions, 146 deletions
diff --git a/include/llvm/Function.h b/include/llvm/Function.h
index 627b47f9d9..20a43e285c 100644
--- a/include/llvm/Function.h
+++ b/include/llvm/Function.h
@@ -158,6 +158,16 @@ public:
return ParamAttrs && ParamAttrs->paramHasAttr(i, attr);
}
+ /// @brief Determine if the function does not access memory.
+ bool doesNotAccessMemory() const {
+ return paramHasAttr(0, ParamAttr::ReadNone);
+ }
+
+ /// @brief Determine if the function does not access or only reads memory.
+ bool onlyReadsMemory() const {
+ return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
+ }
+
/// @brief Determine if the function returns a structure.
bool isStructReturn() const {
return paramHasAttr(1, ParamAttr::StructRet);
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 34b22c7802..2d721bb414 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -927,6 +927,21 @@ public:
/// @brief Determine whether the call or the callee has the given attribute.
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+ /// @brief Determine if the call does not access memory.
+ bool doesNotAccessMemory() const {
+ return paramHasAttr(0, ParamAttr::ReadNone);
+ }
+
+ /// @brief Determine if the call does not access or only reads memory.
+ bool onlyReadsMemory() const {
+ return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
+ }
+
+ /// @brief Determine if the call cannot unwind.
+ bool isNoUnwind() const {
+ return paramHasAttr(0, ParamAttr::NoUnwind);
+ }
+
/// @brief Determine if the call returns a structure.
bool isStructReturn() const {
// Be friendly and also check the callee.
@@ -1711,6 +1726,21 @@ public:
/// @brief Determine whether the call or the callee has the given attribute.
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+ /// @brief Determine if the call does not access memory.
+ bool doesNotAccessMemory() const {
+ return paramHasAttr(0, ParamAttr::ReadNone);
+ }
+
+ /// @brief Determine if the call does not access or only reads memory.
+ bool onlyReadsMemory() const {
+ return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
+ }
+
+ /// @brief Determine if the call cannot unwind.
+ bool isNoUnwind() const {
+ return paramHasAttr(0, ParamAttr::NoUnwind);
+ }
+
/// @brief Determine if the call returns a structure.
bool isStructReturn() const {
// Be friendly and also check the callee.
diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h
index 3a97b33358..47662501d6 100644
--- a/include/llvm/Intrinsics.h
+++ b/include/llvm/Intrinsics.h
@@ -22,6 +22,7 @@ class Type;
class FunctionType;
class Function;
class Module;
+class ParamAttrsList;
/// Intrinsic Namespace - This namespace contains an enum with a value for
/// every intrinsic/builtin function known by LLVM. These enum values are
@@ -46,6 +47,10 @@ namespace Intrinsic {
///
const FunctionType *getType(ID id, const Type **Tys = 0, unsigned numTys = 0);
+ /// Intrinsic::getParamAttrs(ID) - Return the attributes for an intrinsic.
+ ///
+ const ParamAttrsList *getParamAttrs(ID id);
+
/// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function
/// declaration for an intrinsic, and return it.
Function *getDeclaration(Module *M, ID id, const Type **Tys = 0,
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index b613dffe97..5bb60a8a8a 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -67,6 +67,12 @@ public:
/// paramHasAttr - whether the call or the callee has the given attribute.
bool paramHasAttr(uint16_t i, ParameterAttributes attr) const;
+ /// @brief Determine if the call does not access memory.
+ bool doesNotAccessMemory() const;
+
+ /// @brief Determine if the call does not access or only reads memory.
+ bool onlyReadsMemory() const;
+
/// getType - Return the type of the instruction that generated this call site
///
const Type *getType() const { return I->getType(); }
diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp
index 9e1ae2a0d2..12ea937fa9 100644
--- a/lib/Analysis/AliasAnalysis.cpp
+++ b/lib/Analysis/AliasAnalysis.cpp
@@ -116,13 +116,13 @@ AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
AliasAnalysis::ModRefBehavior
AliasAnalysis::getModRefBehavior(CallSite CS,
std::vector<PointerAccessInfo> *Info) {
- if (CS.paramHasAttr(0, ParamAttr::ReadNone))
+ if (CS.doesNotAccessMemory())
// Can't do better than this.
return DoesNotAccessMemory;
ModRefBehavior MRB = UnknownModRefBehavior;
if (Function *F = CS.getCalledFunction())
MRB = getModRefBehavior(F, CS, Info);
- if (MRB != DoesNotAccessMemory && CS.paramHasAttr(0, ParamAttr::ReadOnly))
+ if (MRB != DoesNotAccessMemory && CS.onlyReadsMemory())
return OnlyReadsMemory;
return MRB;
}
@@ -130,11 +130,11 @@ AliasAnalysis::getModRefBehavior(CallSite CS,
AliasAnalysis::ModRefBehavior
AliasAnalysis::getModRefBehavior(Function *F,
std::vector<PointerAccessInfo> *Info) {
- if (F->paramHasAttr(0, ParamAttr::ReadNone))
+ if (F->doesNotAccessMemory())
// Can't do better than this.
return DoesNotAccessMemory;
ModRefBehavior MRB = getModRefBehavior(F, CallSite(), Info);
- if (MRB != DoesNotAccessMemory && F->paramHasAttr(0, ParamAttr::ReadOnly))
+ if (MRB != DoesNotAccessMemory && F->onlyReadsMemory())
return OnlyReadsMemory;
return MRB;
}
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 5ec9afaec9..99d9499a52 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -25,8 +25,6 @@
#include "llvm/Pass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
@@ -116,9 +114,6 @@ namespace {
/// global) or not.
bool pointsToConstantMemory(const Value *P);
- virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
- std::vector<PointerAccessInfo> *Info);
-
private:
// CheckGEPInstructions - Check two GEP instructions with known
// must-aliasing base pointers. This checks to see if the index expressions
@@ -810,37 +805,5 @@ BasicAliasAnalysis::CheckGEPInstructions(
return MayAlias;
}
-static ManagedStatic<BitVector> NoMemoryIntrinsics;
-static ManagedStatic<BitVector> OnlyReadsMemoryIntrinsics;
-
-AliasAnalysis::ModRefBehavior
-BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS,
- std::vector<PointerAccessInfo> *Info) {
- if (!F->isDeclaration()) return UnknownModRefBehavior;
-
- static bool Initialized = false;
- if (!Initialized) {
- NoMemoryIntrinsics->resize(Intrinsic::num_intrinsics);
- OnlyReadsMemoryIntrinsics->resize(Intrinsic::num_intrinsics);
-#define GET_MODREF_BEHAVIOR
-#include "llvm/Intrinsics.gen"
-#undef GET_MODREF_BEHAVIOR
-
- Initialized = true;
- }
-
- // If this is an intrinsic, we can use lookup tables
- if (unsigned id = F->getIntrinsicID()) {
- if (NoMemoryIntrinsics->test(id))
- return DoesNotAccessMemory;
- if (OnlyReadsMemoryIntrinsics->test(id))
- return OnlyReadsMemory;
-
- return UnknownModRefBehavior;
- }
-
- return UnknownModRefBehavior;
-}
-
// Make sure that anything that uses AliasAnalysis pulls in this file...
DEFINING_FILE_FOR(BasicAliasAnalysis)
diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp
index 5f9850c93d..e26ad7a7aa 100644
--- a/lib/Analysis/IPA/CallGraph.cpp
+++ b/lib/Analysis/IPA/CallGraph.cpp
@@ -136,7 +136,7 @@ private:
// If this function is not defined in this translation unit, it could call
// anything.
- if (F->isDeclaration() && !F->getIntrinsicID())
+ if (F->isDeclaration() && !F->isIntrinsic())
Node->addCalledFunction(CallSite(), CallsExternalNode);
// Loop over all of the users of the function... looking for callers...
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index a350ea95f7..ed89878a0d 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2417,31 +2417,13 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
I.isVolatile(), I.getAlignment()));
}
-/// IntrinsicCannotAccessMemory - Return true if the specified intrinsic cannot
-/// access memory and has no other side effects at all.
-static bool IntrinsicCannotAccessMemory(unsigned IntrinsicID) {
-#define GET_NO_MEMORY_INTRINSICS
-#include "llvm/Intrinsics.gen"
-#undef GET_NO_MEMORY_INTRINSICS
- return false;
-}
-
-// 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;
-}
-
/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
/// node.
void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
unsigned Intrinsic) {
- bool HasChain = !IntrinsicCannotAccessMemory(Intrinsic);
- bool OnlyLoad = HasChain && IntrinsicOnlyReadsMemory(Intrinsic);
-
+ bool HasChain = !I.doesNotAccessMemory();
+ bool OnlyLoad = HasChain && I.onlyReadsMemory();
+
// Build the operand list.
SmallVector<SDOperand, 8> Ops;
if (HasChain) { // If this intrinsic has side-effects, chainify it.
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 2d18468215..54a5f426cb 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -1551,7 +1551,7 @@ bool CWriter::doInitialization(Module &M) {
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
// Don't print declarations for intrinsic functions.
- if (!I->getIntrinsicID() && I->getName() != "setjmp" &&
+ if (!I->isIntrinsic() && I->getName() != "setjmp" &&
I->getName() != "longjmp" && I->getName() != "_setjmp") {
if (I->hasExternalWeakLinkage())
Out << "extern ";
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
index dafdbe7b2e..87107d8908 100644
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ b/lib/Target/MSIL/MSILWriter.cpp
@@ -1586,7 +1586,7 @@ void MSILWriter::printExternals() {
// Functions.
for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) {
// Skip intrisics
- if (I->getIntrinsicID()) continue;
+ if (I->isIntrinsic()) continue;
if (I->isDeclaration()) {
const Function* F = I;
std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index a76a43a20b..446b9652e1 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -284,7 +284,7 @@ void DAE::SurveyFunction(Function &F) {
Liveness RetValLiveness = F.getReturnType() == Type::VoidTy ? Live : Dead;
if (!F.hasInternalLinkage() &&
- (!ShouldHackArguments() || F.getIntrinsicID()))
+ (!ShouldHackArguments() || F.isIntrinsic()))
FunctionIntrinsicallyLive = true;
else
for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) {
diff --git a/lib/Transforms/Scalar/LowerGC.cpp b/lib/Transforms/Scalar/LowerGC.cpp
index aff3f2cb30..9935a84cda 100644
--- a/lib/Transforms/Scalar/LowerGC.cpp
+++ b/lib/Transforms/Scalar/LowerGC.cpp
@@ -177,7 +177,7 @@ bool LowerGC::runOnFunction(Function &F) {
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;)
if (CallInst *CI = dyn_cast<CallInst>(II++)) {
if (!CI->getCalledFunction() ||
- !CI->getCalledFunction()->getIntrinsicID())
+ !CI->getCalledFunction()->isIntrinsic())
NormalCalls.push_back(CI); // Remember all normal function calls.
if (Function *F = CI->getCalledFunction())
diff --git a/lib/Transforms/Scalar/SimplifyCFG.cpp b/lib/Transforms/Scalar/SimplifyCFG.cpp
index 259f4d1626..eb1ed4e60d 100644
--- a/lib/Transforms/Scalar/SimplifyCFG.cpp
+++ b/lib/Transforms/Scalar/SimplifyCFG.cpp
@@ -135,7 +135,7 @@ static bool MarkAliveBlocks(BasicBlock *BB,
// Turn invokes that call 'nounwind' functions into ordinary calls.
if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
- if (II->paramHasAttr(0, ParamAttr::NoUnwind)) {
+ if (II->isNoUnwind()) {
ChangeToCall(II);
Changed = true;
}
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index 2a6d9ae9a2..e9f6b28e98 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -69,13 +69,11 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
if (!isa<CallInst>(I)) continue;
CallInst *CI = cast<CallInst>(I);
- // If this is an intrinsic function call or an inline asm, don't
+ // If this call cannot unwind or is an inline asm, don't
// convert it to an invoke.
- if ((CI->getCalledFunction() &&
- CI->getCalledFunction()->getIntrinsicID()) ||
- isa<InlineAsm>(CI->getCalledValue()))
+ if (CI->isNoUnwind() || isa<InlineAsm>(CI->getCalledValue()))
continue;
-
+
// Convert this function call into an invoke instruction.
// First, split the basic block.
BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc");
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index 40c431c279..311941f0d7 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 37949559aa..04db3aa06c 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 a3687530de..9b208854ba 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 7ad588c72e..0df0466112 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 8b8ba598ef..8689c86d08 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.
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index c9780e2210..6bf42d4c51 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -685,7 +685,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
// Use the function we just added to get addresses of functions we need.
for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
if (F->isDeclaration() && !F->use_empty() && &*F != resolverFunc &&
- F->getIntrinsicID() == 0 /* ignore intrinsics */) {
+ !F->isIntrinsic() /* ignore intrinsics */) {
Function *TestFn = Test->getFunction(F->getName());
// Don't forward functions which are external in the test module too.
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index b7c8093875..47569f3d41 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -42,14 +42,8 @@ void IntrinsicEmitter::run(std::ostream &OS) {
// Emit the intrinsic declaration generator.
EmitGenerator(Ints, OS);
- // Emit mod/ref info for each function.
- EmitModRefInfo(Ints, OS);
-
- // Emit table of non-memory accessing intrinsics.
- EmitNoMemoryInfo(Ints, OS);
-
- // Emit side effect info for each intrinsic.
- EmitSideEffectInfo(Ints, OS);
+ // Emit the intrinsic parameter attributes.
+ EmitAttributes(Ints, OS);
// Emit a list of intrinsics with corresponding GCC builtins.
EmitGCCBuiltinList(Ints, OS);
@@ -297,30 +291,11 @@ void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
OS << "#endif\n\n";
}
-void IntrinsicEmitter::EmitModRefInfo(const std::vector<CodeGenIntrinsic> &Ints,
- std::ostream &OS) {
- OS << "// BasicAliasAnalysis code.\n";
- OS << "#ifdef GET_MODREF_BEHAVIOR\n";
- for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
- switch (Ints[i].ModRef) {
- default: break;
- case CodeGenIntrinsic::NoMem:
- OS << " NoMemoryIntrinsics->set(Intrinsic::" << Ints[i].EnumName << ");\n";
- break;
- case CodeGenIntrinsic::ReadArgMem:
- case CodeGenIntrinsic::ReadMem:
- OS << " OnlyReadsMemoryIntrinsics->set(Intrinsic::" << Ints[i].EnumName << ");\n";
- break;
- }
- }
- OS << "#endif\n\n";
-}
-
void IntrinsicEmitter::
-EmitNoMemoryInfo(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
- OS << "// SelectionDAGIsel code.\n";
- OS << "#ifdef GET_NO_MEMORY_INTRINSICS\n";
- OS << " switch (IntrinsicID) {\n";
+EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
+ OS << "// Add parameter attributes that are not common to all intrinsics.\n";
+ OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
+ OS << " switch (id) {\n";
OS << " default: break;\n";
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
switch (Ints[i].ModRef) {
@@ -330,28 +305,19 @@ EmitNoMemoryInfo(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
break;
}
}
- OS << " return true; // These intrinsics do not reference memory.\n";
- OS << " }\n";
- OS << "#endif\n\n";
-}
-
-void IntrinsicEmitter::
-EmitSideEffectInfo(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS){
- OS << "// Return true if doesn't access or only reads memory.\n";
- OS << "#ifdef GET_SIDE_EFFECT_INFO\n";
- OS << " switch (IntrinsicID) {\n";
- OS << " default: break;\n";
+ OS << " Attr |= ParamAttr::ReadNone; // These do not access memory.\n";
+ OS << " break;\n";
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
switch (Ints[i].ModRef) {
default: break;
- case CodeGenIntrinsic::NoMem:
case CodeGenIntrinsic::ReadArgMem:
case CodeGenIntrinsic::ReadMem:
OS << " case Intrinsic::" << Ints[i].EnumName << ":\n";
break;
}
}
- OS << " return true; // These intrinsics have no side effects.\n";
+ OS << " Attr |= ParamAttr::ReadOnly; // These do not write memory.\n";
+ OS << " break;\n";
OS << " }\n";
OS << "#endif\n\n";
}
diff --git a/utils/TableGen/IntrinsicEmitter.h b/utils/TableGen/IntrinsicEmitter.h
index fa483ce674..aece7a9bc4 100644
--- a/utils/TableGen/IntrinsicEmitter.h
+++ b/utils/TableGen/IntrinsicEmitter.h
@@ -37,12 +37,8 @@ namespace llvm {
std::ostream &OS);
void EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
std::ostream &OS);
- void EmitModRefInfo(const std::vector<CodeGenIntrinsic> &Ints,
+ void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints,
std::ostream &OS);
- void EmitNoMemoryInfo(const std::vector<CodeGenIntrinsic> &Ints,
- std::ostream &OS);
- void EmitSideEffectInfo(const std::vector<CodeGenIntrinsic> &Ints,
- std::ostream &OS);
void EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints,
std::ostream &OS);
void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,