aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2012-04-24 11:26:46 -0700
committerShih-wei Liao <sliao@google.com>2012-04-24 11:26:46 -0700
commitcf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d (patch)
tree557137810ae9efc96147d672d372e4dabd0a2440 /lib/VMCore
parent4c8fab82874a29dcd2b242533af3ebe7f66bfd74 (diff)
parentfc728fbdc2631ce8f343cf9b7292d218fde7419f (diff)
downloadexternal_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.zip
external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.tar.gz
external_llvm-cf5a1461acaace0f3e7d11fbbcfbf635b8c8ea9d.tar.bz2
Merge with LLVM upstream r155090.
Conflicts: lib/Support/Unix/PathV2.inc Change-Id: I7b89833849f6cbcfa958a33a971d0f7754c9cb2c
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AutoUpgrade.cpp43
-rw-r--r--lib/VMCore/CMakeLists.txt1
-rw-r--r--lib/VMCore/Core.cpp14
-rw-r--r--lib/VMCore/DebugInfoProbe.cpp225
-rw-r--r--lib/VMCore/DebugLoc.cpp5
-rw-r--r--lib/VMCore/Dominators.cpp98
-rw-r--r--lib/VMCore/Instructions.cpp17
-rw-r--r--lib/VMCore/LLVMContext.cpp11
-rw-r--r--lib/VMCore/LLVMContextImpl.h22
-rw-r--r--lib/VMCore/Metadata.cpp69
-rw-r--r--lib/VMCore/Module.cpp2
-rw-r--r--lib/VMCore/PassManager.cpp23
-rw-r--r--lib/VMCore/Use.cpp1
-rw-r--r--lib/VMCore/Value.cpp33
-rw-r--r--lib/VMCore/Verifier.cpp67
15 files changed, 308 insertions, 323 deletions
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index ea3d4ba..2e16372 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -18,9 +18,6 @@
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/IntrinsicInst.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/ErrorHandling.h"
@@ -59,7 +56,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
if (Name.startswith("x86.sse2.pcmpeq.") ||
Name.startswith("x86.sse2.pcmpgt.") ||
Name.startswith("x86.avx2.pcmpeq.") ||
- Name.startswith("x86.avx2.pcmpgt.")) {
+ Name.startswith("x86.avx2.pcmpgt.") ||
+ Name.startswith("x86.avx.vpermil.")) {
NewFn = 0;
return true;
}
@@ -121,7 +119,42 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// need to sign extend since icmp returns vector of i1
Rep = Builder.CreateSExt(Rep, CI->getType(), "");
} else {
- llvm_unreachable("Unknown function for CallInst upgrade.");
+ bool PD128 = false, PD256 = false, PS128 = false, PS256 = false;
+ if (Name.startswith("llvm.x86.avx.vpermil.pd.256"))
+ PD256 = true;
+ else if (Name.startswith("llvm.x86.avx.vpermil.pd"))
+ PD128 = true;
+ else if (Name.startswith("llvm.x86.avx.vpermil.ps.256"))
+ PS256 = true;
+ else if (Name.startswith("llvm.x86.avx.vpermil.ps"))
+ PS128 = true;
+
+ if (PD256 || PD128 || PS256 || PS128) {
+ Value *Op0 = CI->getArgOperand(0);
+ unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
+ SmallVector<Constant*, 8> Idxs;
+
+ if (PD128)
+ for (unsigned i = 0; i != 2; ++i)
+ Idxs.push_back(Builder.getInt32((Imm >> i) & 0x1));
+ else if (PD256)
+ for (unsigned l = 0; l != 4; l+=2)
+ for (unsigned i = 0; i != 2; ++i)
+ Idxs.push_back(Builder.getInt32(((Imm >> (l+i)) & 0x1) + l));
+ else if (PS128)
+ for (unsigned i = 0; i != 4; ++i)
+ Idxs.push_back(Builder.getInt32((Imm >> (2 * i)) & 0x3));
+ else if (PS256)
+ for (unsigned l = 0; l != 8; l+=4)
+ for (unsigned i = 0; i != 4; ++i)
+ Idxs.push_back(Builder.getInt32(((Imm >> (2 * i)) & 0x3) + l));
+ else
+ llvm_unreachable("Unexpected function");
+
+ Rep = Builder.CreateShuffleVector(Op0, Op0, ConstantVector::get(Idxs));
+ } else {
+ llvm_unreachable("Unknown function for CallInst upgrade.");
+ }
}
CI->replaceAllUsesWith(Rep);
diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt
index 99eeba1..e1efcda 100644
--- a/lib/VMCore/CMakeLists.txt
+++ b/lib/VMCore/CMakeLists.txt
@@ -8,7 +8,6 @@ add_llvm_library(LLVMCore
ConstantFold.cpp
Constants.cpp
Core.cpp
- DebugInfoProbe.cpp
DebugLoc.cpp
Dominators.cpp
Function.cpp
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index e86d805..a9cca22 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -2066,6 +2066,20 @@ LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str,
return wrap(unwrap(B)->CreateGlobalStringPtr(Str, Name));
}
+LLVMBool LLVMGetVolatile(LLVMValueRef MemAccessInst) {
+ Value *P = unwrap<Value>(MemAccessInst);
+ if (LoadInst *LI = dyn_cast<LoadInst>(P))
+ return LI->isVolatile();
+ return cast<StoreInst>(P)->isVolatile();
+}
+
+void LLVMSetVolatile(LLVMValueRef MemAccessInst, LLVMBool isVolatile) {
+ Value *P = unwrap<Value>(MemAccessInst);
+ if (LoadInst *LI = dyn_cast<LoadInst>(P))
+ return LI->setVolatile(isVolatile);
+ return cast<StoreInst>(P)->setVolatile(isVolatile);
+}
+
/*--.. Casts ...............................................................--*/
LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val,
diff --git a/lib/VMCore/DebugInfoProbe.cpp b/lib/VMCore/DebugInfoProbe.cpp
deleted file mode 100644
index d1275ff..0000000
--- a/lib/VMCore/DebugInfoProbe.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-//===-- DebugInfoProbe.cpp - DebugInfo Probe ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements DebugInfoProbe. This probe can be used by a pass
-// manager to analyze how optimizer is treating debugging information.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "debuginfoprobe"
-#include "llvm/DebugInfoProbe.h"
-#include "llvm/Function.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/Metadata.h"
-#include "llvm/PassManager.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/DebugLoc.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/StringRef.h"
-#include <set>
-#include <string>
-
-using namespace llvm;
-
-static cl::opt<bool>
-EnableDebugInfoProbe("enable-debug-info-probe", cl::Hidden,
- cl::desc("Enable debug info probe"));
-
-// CreateInfoOutputFile - Return a file stream to print our output on.
-namespace llvm { extern raw_ostream *CreateInfoOutputFile(); }
-
-//===----------------------------------------------------------------------===//
-// DebugInfoProbeImpl - This class implements a interface to monitor
-// how an optimization pass is preserving debugging information.
-
-namespace llvm {
-
- class DebugInfoProbeImpl {
- public:
- DebugInfoProbeImpl() : NumDbgLineLost(0),NumDbgValueLost(0) {}
- void initialize(StringRef PName, Function &F);
- void finalize(Function &F);
- void report();
- private:
- unsigned NumDbgLineLost, NumDbgValueLost;
- std::string PassName;
- Function *TheFn;
- std::set<MDNode *> DbgVariables;
- std::set<Instruction *> MissingDebugLoc;
- };
-}
-
-//===----------------------------------------------------------------------===//
-// DebugInfoProbeImpl
-
-/// initialize - Collect information before running an optimization pass.
-void DebugInfoProbeImpl::initialize(StringRef PName, Function &F) {
- if (!EnableDebugInfoProbe) return;
- PassName = PName;
-
- DbgVariables.clear();
- MissingDebugLoc.clear();
- TheFn = &F;
-
- for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
- for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
- BI != BE; ++BI) {
- if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown())
- MissingDebugLoc.insert(BI);
- if (!isa<DbgInfoIntrinsic>(BI)) continue;
- Value *Addr = NULL;
- MDNode *Node = NULL;
- if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
- Addr = DDI->getAddress();
- Node = DDI->getVariable();
- } else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) {
- Addr = DVI->getValue();
- Node = DVI->getVariable();
- }
- if (Addr)
- DbgVariables.insert(Node);
- }
-}
-
-/// report - Report findings. This should be invoked after finalize.
-void DebugInfoProbeImpl::report() {
- if (!EnableDebugInfoProbe) return;
- if (NumDbgLineLost || NumDbgValueLost) {
- raw_ostream *OutStream = CreateInfoOutputFile();
- if (NumDbgLineLost)
- *OutStream << NumDbgLineLost
- << "\t times line number info lost by "
- << PassName << "\n";
- if (NumDbgValueLost)
- *OutStream << NumDbgValueLost
- << "\t times variable info lost by "
- << PassName << "\n";
- delete OutStream;
- }
- NumDbgLineLost = 0;
- NumDbgValueLost = 0;
-}
-
-/// finalize - Collect information after running an optimization pass. This
-/// must be used after initialization.
-void DebugInfoProbeImpl::finalize(Function &F) {
- if (!EnableDebugInfoProbe) return;
- assert (TheFn == &F && "Invalid function to measure!");
-
- std::set<MDNode *>DbgVariables2;
- for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
- for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
- BI != BE; ++BI) {
- if (!isa<PHINode>(BI) && BI->getDebugLoc().isUnknown() &&
- MissingDebugLoc.count(BI) == 0) {
- ++NumDbgLineLost;
- DEBUG(dbgs() << "DebugInfoProbe (" << PassName << "): --- ");
- DEBUG(BI->print(dbgs()));
- DEBUG(dbgs() << "\n");
- }
- if (!isa<DbgInfoIntrinsic>(BI)) continue;
- Value *Addr = NULL;
- MDNode *Node = NULL;
- if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) {
- Addr = DDI->getAddress();
- Node = DDI->getVariable();
- } else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) {
- Addr = DVI->getValue();
- Node = DVI->getVariable();
- }
- if (Addr)
- DbgVariables2.insert(Node);
- }
-
- for (std::set<MDNode *>::iterator I = DbgVariables.begin(),
- E = DbgVariables.end(); I != E; ++I) {
- if (DbgVariables2.count(*I) == 0 && (*I)->getNumOperands() >= 2) {
- DEBUG(dbgs()
- << "DebugInfoProbe("
- << PassName
- << "): Losing dbg info for variable: ";
- if (MDString *MDS = dyn_cast_or_null<MDString>(
- (*I)->getOperand(2)))
- dbgs() << MDS->getString();
- else
- dbgs() << "...";
- dbgs() << "\n");
- ++NumDbgValueLost;
- }
- }
-}
-
-//===----------------------------------------------------------------------===//
-// DebugInfoProbe
-
-DebugInfoProbe::DebugInfoProbe() {
- pImpl = new DebugInfoProbeImpl();
-}
-
-DebugInfoProbe::~DebugInfoProbe() {
- delete pImpl;
-}
-
-/// initialize - Collect information before running an optimization pass.
-void DebugInfoProbe::initialize(StringRef PName, Function &F) {
- pImpl->initialize(PName, F);
-}
-
-/// finalize - Collect information after running an optimization pass. This
-/// must be used after initialization.
-void DebugInfoProbe::finalize(Function &F) {
- pImpl->finalize(F);
-}
-
-/// report - Report findings. This should be invoked after finalize.
-void DebugInfoProbe::report() {
- pImpl->report();
-}
-
-//===----------------------------------------------------------------------===//
-// DebugInfoProbeInfo
-
-/// ~DebugInfoProbeInfo - Report data collected by all probes before deleting
-/// them.
-DebugInfoProbeInfo::~DebugInfoProbeInfo() {
- if (!EnableDebugInfoProbe) return;
- for (StringMap<DebugInfoProbe*>::iterator I = Probes.begin(),
- E = Probes.end(); I != E; ++I) {
- I->second->report();
- delete I->second;
- }
- }
-
-/// initialize - Collect information before running an optimization pass.
-void DebugInfoProbeInfo::initialize(Pass *P, Function &F) {
- if (!EnableDebugInfoProbe) return;
- if (P->getAsPMDataManager())
- return;
-
- StringMapEntry<DebugInfoProbe *> &Entry =
- Probes.GetOrCreateValue(P->getPassName());
- DebugInfoProbe *&Probe = Entry.getValue();
- if (!Probe)
- Probe = new DebugInfoProbe();
- Probe->initialize(P->getPassName(), F);
-}
-
-/// finalize - Collect information after running an optimization pass. This
-/// must be used after initialization.
-void DebugInfoProbeInfo::finalize(Pass *P, Function &F) {
- if (!EnableDebugInfoProbe) return;
- if (P->getAsPMDataManager())
- return;
- StringMapEntry<DebugInfoProbe *> &Entry =
- Probes.GetOrCreateValue(P->getPassName());
- DebugInfoProbe *&Probe = Entry.getValue();
- assert (Probe && "DebugInfoProbe is not initialized!");
- Probe->finalize(F);
-}
diff --git a/lib/VMCore/DebugLoc.cpp b/lib/VMCore/DebugLoc.cpp
index 328244f..9013d28 100644
--- a/lib/VMCore/DebugLoc.cpp
+++ b/lib/VMCore/DebugLoc.cpp
@@ -173,10 +173,7 @@ DebugLoc DenseMapInfo<DebugLoc>::getTombstoneKey() {
}
unsigned DenseMapInfo<DebugLoc>::getHashValue(const DebugLoc &Key) {
- FoldingSetNodeID ID;
- ID.AddInteger(Key.LineCol);
- ID.AddInteger(Key.ScopeIdx);
- return ID.ComputeHash();
+ return static_cast<unsigned>(hash_combine(Key.LineCol, Key.ScopeIdx));
}
bool DenseMapInfo<DebugLoc>::isEqual(const DebugLoc &LHS, const DebugLoc &RHS) {
diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp
index af51a05..219e631 100644
--- a/lib/VMCore/Dominators.cpp
+++ b/lib/VMCore/Dominators.cpp
@@ -88,8 +88,13 @@ bool DominatorTree::dominates(const Instruction *Def,
const BasicBlock *UseBB = User->getParent();
const BasicBlock *DefBB = Def->getParent();
- assert(isReachableFromEntry(DefBB) && isReachableFromEntry(UseBB) &&
- "We only handle reachable blocks");
+ // Any unreachable use is dominated, even if Def == User.
+ if (!isReachableFromEntry(UseBB))
+ return true;
+
+ // Unreachable definitions don't dominate anything.
+ if (!isReachableFromEntry(DefBB))
+ return false;
// An instruction doesn't dominate a use in itself.
if (Def == User)
@@ -119,8 +124,13 @@ bool DominatorTree::dominates(const Instruction *Def,
const BasicBlock *UseBB) const {
const BasicBlock *DefBB = Def->getParent();
- assert(isReachableFromEntry(DefBB) && isReachableFromEntry(UseBB) &&
- "We only handle reachable blocks");
+ // Any unreachable use is dominated, even if DefBB == UseBB.
+ if (!isReachableFromEntry(UseBB))
+ return true;
+
+ // Unreachable definitions don't dominate anything.
+ if (!isReachableFromEntry(DefBB))
+ return false;
if (DefBB == UseBB)
return false;
@@ -174,3 +184,83 @@ bool DominatorTree::dominates(const Instruction *Def,
}
return true;
}
+
+bool DominatorTree::dominates(const Instruction *Def,
+ const Use &U) const {
+ Instruction *UserInst = dyn_cast<Instruction>(U.getUser());
+
+ // Instructions do not dominate non-instructions.
+ if (!UserInst)
+ return false;
+
+ const BasicBlock *DefBB = Def->getParent();
+
+ // Determine the block in which the use happens. PHI nodes use
+ // their operands on edges; simulate this by thinking of the use
+ // happening at the end of the predecessor block.
+ const BasicBlock *UseBB;
+ if (PHINode *PN = dyn_cast<PHINode>(UserInst))
+ UseBB = PN->getIncomingBlock(U);
+ else
+ UseBB = UserInst->getParent();
+
+ // Any unreachable use is dominated, even if Def == User.
+ if (!isReachableFromEntry(UseBB))
+ return true;
+
+ // Unreachable definitions don't dominate anything.
+ if (!isReachableFromEntry(DefBB))
+ return false;
+
+ // Invoke instructions define their return values on the edges
+ // to their normal successors, so we have to handle them specially.
+ // Among other things, this means they don't dominate anything in
+ // their own block, except possibly a phi, so we don't need to
+ // walk the block in any case.
+ if (const InvokeInst *II = dyn_cast<InvokeInst>(Def)) {
+ // A PHI in the normal successor using the invoke's return value is
+ // dominated by the invoke's return value.
+ if (isa<PHINode>(UserInst) &&
+ UserInst->getParent() == II->getNormalDest() &&
+ cast<PHINode>(UserInst)->getIncomingBlock(U) == DefBB)
+ return true;
+
+ // Otherwise use the instruction-dominates-block query, which
+ // handles the crazy case of an invoke with a critical edge
+ // properly.
+ return dominates(Def, UseBB);
+ }
+
+ // If the def and use are in different blocks, do a simple CFG dominator
+ // tree query.
+ if (DefBB != UseBB)
+ return dominates(DefBB, UseBB);
+
+ // Ok, def and use are in the same block. If the def is an invoke, it
+ // doesn't dominate anything in the block. If it's a PHI, it dominates
+ // everything in the block.
+ if (isa<PHINode>(UserInst))
+ return true;
+
+ // Otherwise, just loop through the basic block until we find Def or User.
+ BasicBlock::const_iterator I = DefBB->begin();
+ for (; &*I != Def && &*I != UserInst; ++I)
+ /*empty*/;
+
+ return &*I != UserInst;
+}
+
+bool DominatorTree::isReachableFromEntry(const Use &U) const {
+ Instruction *I = dyn_cast<Instruction>(U.getUser());
+
+ // ConstantExprs aren't really reachable from the entry block, but they
+ // don't need to be treated like unreachable code either.
+ if (!I) return true;
+
+ // PHI nodes use their operands on their incoming edges.
+ if (PHINode *PN = dyn_cast<PHINode>(I))
+ return isReachableFromEntry(PN->getIncomingBlock(U));
+
+ // Everything else uses their operands in their own block.
+ return isReachableFromEntry(I->getParent());
+}
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 8db6ac9..6c5db32 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -2003,6 +2003,23 @@ bool BinaryOperator::isExact() const {
}
//===----------------------------------------------------------------------===//
+// FPMathOperator Class
+//===----------------------------------------------------------------------===//
+
+/// getFPAccuracy - Get the maximum error permitted by this operation in ULPs.
+/// An accuracy of 0.0 means that the operation should be performed with the
+/// default precision.
+float FPMathOperator::getFPAccuracy() const {
+ const MDNode *MD =
+ cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath);
+ if (!MD)
+ return 0.0;
+ ConstantFP *Accuracy = cast<ConstantFP>(MD->getOperand(0));
+ return Accuracy->getValueAPF().convertToFloat();
+}
+
+
+//===----------------------------------------------------------------------===//
// CastInst Class
//===----------------------------------------------------------------------===//
diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp
index d77e996..f07f0b3 100644
--- a/lib/VMCore/LLVMContext.cpp
+++ b/lib/VMCore/LLVMContext.cpp
@@ -44,10 +44,15 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
unsigned ProfID = getMDKindID("prof");
assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID;
- // Create the 'fpaccuracy' metadata kind.
- unsigned FPAccuracyID = getMDKindID("fpaccuracy");
- assert(FPAccuracyID == MD_fpaccuracy && "fpaccuracy kind id drifted");
+ // Create the 'fpmath' metadata kind.
+ unsigned FPAccuracyID = getMDKindID("fpmath");
+ assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted");
(void)FPAccuracyID;
+
+ // Create the 'range' metadata kind.
+ unsigned RangeID = getMDKindID("range");
+ assert(RangeID == MD_range && "range kind id drifted");
+ (void)RangeID;
}
LLVMContext::~LLVMContext() { delete pImpl; }
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index f98526d..2252028 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -194,6 +194,26 @@ struct FunctionTypeKeyInfo {
}
};
+// Provide a FoldingSetTrait::Equals specialization for MDNode that can use a
+// shortcut to avoid comparing all operands.
+template<> struct FoldingSetTrait<MDNode> : DefaultFoldingSetTrait<MDNode> {
+ static bool Equals(const MDNode &X, const FoldingSetNodeID &ID,
+ unsigned IDHash, FoldingSetNodeID &TempID) {
+ assert(!X.isNotUniqued() && "Non-uniqued MDNode in FoldingSet?");
+ // First, check if the cached hashes match. If they don't we can skip the
+ // expensive operand walk.
+ if (X.Hash != IDHash)
+ return false;
+
+ // If they match we have to compare the operands.
+ X.Profile(TempID);
+ return TempID == ID;
+ }
+ static unsigned ComputeHash(const MDNode &X, FoldingSetNodeID &) {
+ return X.Hash; // Return cached hash.
+ }
+};
+
/// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps
/// up to date as MDNodes mutate. This class is implemented in DebugLoc.cpp.
class DebugRecVH : public CallbackVH {
@@ -234,7 +254,7 @@ public:
DenseMapAPFloatKeyInfo> FPMapTy;
FPMapTy FPConstants;
- StringMap<MDString*> MDStringCache;
+ StringMap<Value*> MDStringCache;
FoldingSet<MDNode> MDNodeSet;
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index 0fc2a25..090b09a 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -31,16 +31,17 @@ using namespace llvm;
void MDString::anchor() { }
-MDString::MDString(LLVMContext &C, StringRef S)
- : Value(Type::getMetadataTy(C), Value::MDStringVal), Str(S) {}
+MDString::MDString(LLVMContext &C)
+ : Value(Type::getMetadataTy(C), Value::MDStringVal) {}
MDString *MDString::get(LLVMContext &Context, StringRef Str) {
LLVMContextImpl *pImpl = Context.pImpl;
- StringMapEntry<MDString *> &Entry =
+ StringMapEntry<Value*> &Entry =
pImpl->MDStringCache.GetOrCreateValue(Str);
- MDString *&S = Entry.getValue();
- if (!S) S = new MDString(Context, Entry.getKey());
- return S;
+ Value *&S = Entry.getValue();
+ if (!S) S = new MDString(Context);
+ S->setValueName(&Entry);
+ return cast<MDString>(S);
}
//===----------------------------------------------------------------------===//
@@ -50,14 +51,26 @@ MDString *MDString::get(LLVMContext &Context, StringRef Str) {
// Use CallbackVH to hold MDNode operands.
namespace llvm {
class MDNodeOperand : public CallbackVH {
- MDNode *Parent;
+ MDNode *getParent() {
+ MDNodeOperand *Cur = this;
+
+ while (Cur->getValPtrInt() != 1)
+ --Cur;
+
+ assert(Cur->getValPtrInt() == 1 &&
+ "Couldn't find the beginning of the operand list!");
+ return reinterpret_cast<MDNode*>(Cur) - 1;
+ }
+
public:
- MDNodeOperand(Value *V, MDNode *P) : CallbackVH(V), Parent(P) {}
+ MDNodeOperand(Value *V) : CallbackVH(V) {}
~MDNodeOperand() {}
- void set(Value *V) {
- setValPtr(V);
- }
+ void set(Value *V) { this->setValPtr(V); }
+
+ /// setAsFirstOperand - Accessor method to mark the operand as the first in
+ /// the list.
+ void setAsFirstOperand(unsigned V) { this->setValPtrInt(V); }
virtual void deleted();
virtual void allUsesReplacedWith(Value *NV);
@@ -66,15 +79,13 @@ public:
void MDNodeOperand::deleted() {
- Parent->replaceOperand(this, 0);
+ getParent()->replaceOperand(this, 0);
}
void MDNodeOperand::allUsesReplacedWith(Value *NV) {
- Parent->replaceOperand(this, NV);
+ getParent()->replaceOperand(this, NV);
}
-
-
//===----------------------------------------------------------------------===//
// MDNode implementation.
//
@@ -102,8 +113,13 @@ MDNode::MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal)
// Initialize the operand list, which is co-allocated on the end of the node.
unsigned i = 0;
for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
- Op != E; ++Op, ++i)
- new (Op) MDNodeOperand(Vals[i], this);
+ Op != E; ++Op, ++i) {
+ new (Op) MDNodeOperand(Vals[i]);
+
+ // Mark the first MDNodeOperand as being the first in the list of operands.
+ if (i == 0)
+ Op->setAsFirstOperand(1);
+ }
}
@@ -205,11 +221,11 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals,
ID.AddPointer(Vals[i]);
void *InsertPoint;
- MDNode *N = NULL;
-
- if ((N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint)))
+ MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
+
+ if (N || !Insert)
return N;
-
+
bool isFunctionLocal = false;
switch (FL) {
case FL_Unknown:
@@ -234,6 +250,9 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals,
void *Ptr = malloc(sizeof(MDNode)+Vals.size()*sizeof(MDNodeOperand));
N = new (Ptr) MDNode(Context, Vals, isFunctionLocal);
+ // Cache the operand hash.
+ N->Hash = ID.ComputeHash();
+
// InsertPoint will have been set by the FindNodeOrInsertPos call.
pImpl->MDNodeSet.InsertNode(N, InsertPoint);
@@ -357,6 +376,8 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {
return;
}
+ // Cache the operand hash.
+ Hash = ID.ComputeHash();
// InsertPoint will have been set by the FindNodeOrInsertPos call.
pImpl->MDNodeSet.InsertNode(this, InsertPoint);
@@ -551,17 +572,15 @@ getAllMetadataOtherThanDebugLocImpl(SmallVectorImpl<std::pair<unsigned,
getContext().pImpl->MetadataStore.count(this) &&
"Shouldn't have called this");
const LLVMContextImpl::MDMapTy &Info =
- getContext().pImpl->MetadataStore.find(this)->second;
+ getContext().pImpl->MetadataStore.find(this)->second;
assert(!Info.empty() && "Shouldn't have called this");
-
Result.append(Info.begin(), Info.end());
-
+
// Sort the resulting array so it is stable.
if (Result.size() > 1)
array_pod_sort(Result.begin(), Result.end());
}
-
/// clearMetadataHashEntries - Clear all hashtable-based metadata from
/// this instruction.
void Instruction::clearMetadataHashEntries() {
diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp
index e8bc6db..3c67191 100644
--- a/lib/VMCore/Module.cpp
+++ b/lib/VMCore/Module.cpp
@@ -434,7 +434,7 @@ bool Module::MaterializeAllPermanently(std::string *ErrInfo) {
//
-// dropAllReferences() - This function causes all the subelementss to "let go"
+// dropAllReferences() - This function causes all the subelements to "let go"
// of all references that they are maintaining. This allows one to 'delete' a
// whole module at a time, even though there may be circular references... first
// all references are dropped, and all use counts go to zero. Then everything
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index 773862d..28fbaa6 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -14,7 +14,6 @@
#include "llvm/PassManagers.h"
#include "llvm/PassManager.h"
-#include "llvm/DebugInfoProbe.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CommandLine.h"
@@ -26,7 +25,6 @@
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Mutex.h"
-#include "llvm/ADT/StringMap.h"
#include <algorithm>
#include <map>
using namespace llvm;
@@ -422,20 +420,6 @@ char PassManagerImpl::ID = 0;
namespace {
//===----------------------------------------------------------------------===//
-// DebugInfoProbe
-
-static DebugInfoProbeInfo *TheDebugProbe;
-static void createDebugInfoProbe() {
- if (TheDebugProbe) return;
-
- // Constructed the first time this is called. This guarantees that the
- // object will be constructed, if -enable-debug-info-probe is set,
- // before static globals, thus it will be destroyed before them.
- static ManagedStatic<DebugInfoProbeInfo> DIP;
- TheDebugProbe = &*DIP;
-}
-
-//===----------------------------------------------------------------------===//
/// TimingInfo Class - This class is used to calculate information about the
/// amount of time each pass takes to execute. This only happens when
/// -time-passes is enabled on the command line.
@@ -1440,7 +1424,6 @@ void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
bool FunctionPassManagerImpl::run(Function &F) {
bool Changed = false;
TimingInfo::createTheTimeInfo();
- createDebugInfoProbe();
initializeAllAnalysisInfo();
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
@@ -1488,16 +1471,13 @@ bool FPPassManager::runOnFunction(Function &F) {
dumpRequiredSet(FP);
initializeAnalysisImpl(FP);
- if (TheDebugProbe)
- TheDebugProbe->initialize(FP, F);
+
{
PassManagerPrettyStackEntry X(FP, F);
TimeRegion PassTimer(getPassTimer(FP));
LocalChanged |= FP->runOnFunction(F);
}
- if (TheDebugProbe)
- TheDebugProbe->finalize(FP, F);
Changed |= LocalChanged;
if (LocalChanged)
@@ -1647,7 +1627,6 @@ Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){
bool PassManagerImpl::run(Module &M) {
bool Changed = false;
TimingInfo::createTheTimeInfo();
- createDebugInfoProbe();
dumpArguments();
dumpPasses();
diff --git a/lib/VMCore/Use.cpp b/lib/VMCore/Use.cpp
index 359a151..0128adc 100644
--- a/lib/VMCore/Use.cpp
+++ b/lib/VMCore/Use.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Value.h"
+#include <new>
namespace llvm {
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index 41cc38c..4006b2c 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -76,7 +76,7 @@ Value::~Value() {
// If this value is named, destroy the name. This should not be in a symtab
// at this point.
- if (Name)
+ if (Name && SubclassID != MDStringVal)
Name->Destroy();
// There should be no uses of this object anymore, remove it.
@@ -170,6 +170,9 @@ StringRef Value::getName() const {
}
void Value::setName(const Twine &NewName) {
+ assert(SubclassID != MDStringVal &&
+ "Cannot set the name of MDString with this method!");
+
// Fast path for common IRBuilder case of setName("") when there is no name.
if (NewName.isTriviallyEmpty() && !hasName())
return;
@@ -228,6 +231,8 @@ void Value::setName(const Twine &NewName) {
/// takeName - transfer the name from V to this value, setting V's name to
/// empty. It is an error to call V->takeName(V).
void Value::takeName(Value *V) {
+ assert(SubclassID != MDStringVal && "Cannot take the name of an MDString!");
+
ValueSymbolTable *ST = 0;
// If this value has a name, drop it.
if (hasName()) {
@@ -477,7 +482,7 @@ void ValueHandleBase::AddToExistingUseList(ValueHandleBase **List) {
setPrevPtr(List);
if (Next) {
Next->setPrevPtr(&Next);
- assert(VP == Next->VP && "Added to wrong list?");
+ assert(VP.getPointer() == Next->VP.getPointer() && "Added to wrong list?");
}
}
@@ -493,14 +498,14 @@ void ValueHandleBase::AddToExistingUseListAfter(ValueHandleBase *List) {
/// AddToUseList - Add this ValueHandle to the use list for VP.
void ValueHandleBase::AddToUseList() {
- assert(VP && "Null pointer doesn't have a use list!");
+ assert(VP.getPointer() && "Null pointer doesn't have a use list!");
- LLVMContextImpl *pImpl = VP->getContext().pImpl;
+ LLVMContextImpl *pImpl = VP.getPointer()->getContext().pImpl;
- if (VP->HasValueHandle) {
+ if (VP.getPointer()->HasValueHandle) {
// If this value already has a ValueHandle, then it must be in the
// ValueHandles map already.
- ValueHandleBase *&Entry = pImpl->ValueHandles[VP];
+ ValueHandleBase *&Entry = pImpl->ValueHandles[VP.getPointer()];
assert(Entry != 0 && "Value doesn't have any handles?");
AddToExistingUseList(&Entry);
return;
@@ -514,10 +519,10 @@ void ValueHandleBase::AddToUseList() {
DenseMap<Value*, ValueHandleBase*> &Handles = pImpl->ValueHandles;
const void *OldBucketPtr = Handles.getPointerIntoBucketsArray();
- ValueHandleBase *&Entry = Handles[VP];
+ ValueHandleBase *&Entry = Handles[VP.getPointer()];
assert(Entry == 0 && "Value really did already have handles?");
AddToExistingUseList(&Entry);
- VP->HasValueHandle = true;
+ VP.getPointer()->HasValueHandle = true;
// If reallocation didn't happen or if this was the first insertion, don't
// walk the table.
@@ -529,14 +534,16 @@ void ValueHandleBase::AddToUseList() {
// Okay, reallocation did happen. Fix the Prev Pointers.
for (DenseMap<Value*, ValueHandleBase*>::iterator I = Handles.begin(),
E = Handles.end(); I != E; ++I) {
- assert(I->second && I->first == I->second->VP && "List invariant broken!");
+ assert(I->second && I->first == I->second->VP.getPointer() &&
+ "List invariant broken!");
I->second->setPrevPtr(&I->second);
}
}
/// RemoveFromUseList - Remove this ValueHandle from its current use list.
void ValueHandleBase::RemoveFromUseList() {
- assert(VP && VP->HasValueHandle && "Pointer doesn't have a use list!");
+ assert(VP.getPointer() && VP.getPointer()->HasValueHandle &&
+ "Pointer doesn't have a use list!");
// Unlink this from its use list.
ValueHandleBase **PrevPtr = getPrevPtr();
@@ -552,11 +559,11 @@ void ValueHandleBase::RemoveFromUseList() {
// If the Next pointer was null, then it is possible that this was the last
// ValueHandle watching VP. If so, delete its entry from the ValueHandles
// map.
- LLVMContextImpl *pImpl = VP->getContext().pImpl;
+ LLVMContextImpl *pImpl = VP.getPointer()->getContext().pImpl;
DenseMap<Value*, ValueHandleBase*> &Handles = pImpl->ValueHandles;
if (Handles.isPointerIntoBucketsArray(PrevPtr)) {
- Handles.erase(VP);
- VP->HasValueHandle = false;
+ Handles.erase(VP.getPointer());
+ VP.getPointer()->HasValueHandle = false;
}
}
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 5b9b2a5..47baef3 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -51,6 +51,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
@@ -117,7 +118,6 @@ namespace {
struct Verifier : public FunctionPass, public InstVisitor<Verifier> {
static char ID; // Pass ID, replacement for typeid
bool Broken; // Is this module found to be broken?
- bool RealPass; // Are we not being run by a PassManager?
VerifierFailureAction action;
// What to do if verification fails.
Module *Mod; // Module we are verifying right now
@@ -143,13 +143,13 @@ namespace {
const Value *PersonalityFn;
Verifier()
- : FunctionPass(ID), Broken(false), RealPass(true),
+ : FunctionPass(ID), Broken(false),
action(AbortProcessAction), Mod(0), Context(0), DT(0),
MessagesStr(Messages), PersonalityFn(0) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
explicit Verifier(VerifierFailureAction ctn)
- : FunctionPass(ID), Broken(false), RealPass(true), action(ctn), Mod(0),
+ : FunctionPass(ID), Broken(false), action(ctn), Mod(0),
Context(0), DT(0), MessagesStr(Messages), PersonalityFn(0) {
initializeVerifierPass(*PassRegistry::getPassRegistry());
}
@@ -158,17 +158,14 @@ namespace {
Mod = &M;
Context = &M.getContext();
- // If this is a real pass, in a pass manager, we must abort before
- // returning back to the pass manager, or else the pass manager may try to
- // run other passes on the broken module.
- if (RealPass)
- return abortIfBroken();
- return false;
+ // We must abort before returning back to the pass manager, or else the
+ // pass manager may try to run other passes on the broken module.
+ return abortIfBroken();
}
bool runOnFunction(Function &F) {
// Get dominator information if we are being run by PassManager
- if (RealPass) DT = &getAnalysis<DominatorTree>();
+ DT = &getAnalysis<DominatorTree>();
Mod = F.getParent();
if (!Context) Context = &F.getContext();
@@ -177,13 +174,9 @@ namespace {
InstsInThisBlock.clear();
PersonalityFn = 0;
- // If this is a real pass, in a pass manager, we must abort before
- // returning back to the pass manager, or else the pass manager may try to
- // run other passes on the broken module.
- if (RealPass)
- return abortIfBroken();
-
- return false;
+ // We must abort before returning back to the pass manager, or else the
+ // pass manager may try to run other passes on the broken module.
+ return abortIfBroken();
}
bool doFinalization(Module &M) {
@@ -214,8 +207,7 @@ namespace {
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequiredID(PreVerifyID);
- if (RealPass)
- AU.addRequired<DominatorTree>();
+ AU.addRequired<DominatorTree>();
}
/// abortIfBroken - If the module is broken and we are supposed to abort on
@@ -1369,6 +1361,25 @@ void Verifier::visitLoadInst(LoadInst &LI) {
Assert1(LI.getSynchScope() == CrossThread,
"Non-atomic load cannot have SynchronizationScope specified", &LI);
}
+
+ if (MDNode *Range = LI.getMetadata(LLVMContext::MD_range)) {
+ unsigned NumOperands = Range->getNumOperands();
+ Assert1(NumOperands % 2 == 0, "Unfinished range!", Range);
+ unsigned NumRanges = NumOperands / 2;
+ Assert1(NumRanges >= 1, "It should have at least one range!", Range);
+ for (unsigned i = 0; i < NumRanges; ++i) {
+ ConstantInt *Low = dyn_cast<ConstantInt>(Range->getOperand(2*i));
+ Assert1(Low, "The lower limit must be an integer!", Low);
+ ConstantInt *High = dyn_cast<ConstantInt>(Range->getOperand(2*i + 1));
+ Assert1(High, "The upper limit must be an integer!", High);
+ Assert1(High->getType() == Low->getType() &&
+ High->getType() == ElTy, "Range types must match load type!",
+ &LI);
+ Assert1(High->getValue() != Low->getValue(), "Range must not be empty!",
+ Range);
+ }
+ }
+
visitInstruction(LI);
}
@@ -1641,6 +1652,24 @@ void Verifier::visitInstruction(Instruction &I) {
"Cannot take the address of an inline asm!", &I);
}
}
+
+ if (MDNode *MD = I.getMetadata(LLVMContext::MD_fpmath)) {
+ Assert1(I.getType()->isFPOrFPVectorTy(),
+ "fpmath requires a floating point result!", &I);
+ Assert1(MD->getNumOperands() == 1, "fpmath takes one operand!", &I);
+ Value *Op0 = MD->getOperand(0);
+ if (ConstantFP *CFP0 = dyn_cast_or_null<ConstantFP>(Op0)) {
+ APFloat Accuracy = CFP0->getValueAPF();
+ Assert1(Accuracy.isNormal() && !Accuracy.isNegative(),
+ "fpmath accuracy not a positive number!", &I);
+ } else {
+ Assert1(false, "invalid fpmath accuracy!", &I);
+ }
+ }
+
+ MDNode *MD = I.getMetadata(LLVMContext::MD_range);
+ Assert1(!MD || isa<LoadInst>(I), "Ranges are only for loads!", &I);
+
InstsInThisBlock.insert(&I);
}