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 | |
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')
-rw-r--r-- | lib/Analysis/AliasAnalysis.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/BasicAliasAnalysis.cpp | 37 | ||||
-rw-r--r-- | lib/Analysis/IPA/CallGraph.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 24 | ||||
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 2 | ||||
-rw-r--r-- | lib/Target/MSIL/MSILWriter.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/IPO/DeadArgumentElimination.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LowerGC.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyCFG.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 8 | ||||
-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 |
15 files changed, 73 insertions, 96 deletions
diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index 9e1ae2a..12ea937 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 5ec9afa..99d9499 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 5f9850c..e26ad7a 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 a350ea9..ed89878 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 2d18468..54a5f42 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 dafdbe7..87107d8 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 a76a43a..446b965 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 aff3f2c..9935a84 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 259f4d1..eb1ed4e 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 2a6d9ae..e9f6b28 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 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. |