Make GlobalOpt be conservative with TLS variables (PR14309)

For global variables that get the same value stored into them
everywhere, GlobalOpt will replace them with a constant. The problem is
that a thread-local GlobalVariable looks like one value (the address of
the TLS var), but is different between threads.

This patch introduces Constant::isThreadDependent() which returns true
for thread-local variables and constants which depend on them (e.g. a GEP
into a thread-local array), and teaches GlobalOpt not to track such
values.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168037 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hans Wennborg
2012-11-15 11:40:00 +00:00
parent ac39a03535
commit 1839858983
4 changed files with 90 additions and 0 deletions

View File

@@ -245,6 +245,31 @@ bool Constant::canTrap() const {
}
}
/// isThreadDependent - Return true if the value can vary between threads.
bool Constant::isThreadDependent() const {
SmallPtrSet<const Constant*, 64> Visited;
SmallVector<const Constant*, 64> WorkList;
WorkList.push_back(this);
Visited.insert(this);
while (!WorkList.empty()) {
const Constant *C = WorkList.pop_back_val();
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
if (GV->isThreadLocal())
return true;
}
for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I) {
const Constant *D = cast<Constant>(C->getOperand(I));
if (Visited.insert(D))
WorkList.push_back(D);
}
}
return false;
}
/// isConstantUsed - Return true if the constant has users other than constant
/// exprs and other dangling things.
bool Constant::isConstantUsed() const {