summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-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
15 files changed, 73 insertions, 96 deletions
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.