Extend the IL for selecting TLS models (PR9788)

This allows the user/front-end to specify a model that is better
than what LLVM would choose by default. For example, a variable
might be declared as

  @x = thread_local(initialexec) global i32 42

if it will not be used in a shared library that is dlopen'ed.

If the specified model isn't supported by the target, or if LLVM can
make a better choice, a different model may be used.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159077 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hans Wennborg
2012-06-23 11:37:03 +00:00
parent 47cbc4e0ee
commit ce718ff9f4
24 changed files with 707 additions and 48 deletions

View File

@@ -77,6 +77,24 @@ CodeModel::Model TargetMachine::getCodeModel() const {
return CodeGenInfo->getCodeModel();
}
/// Get the IR-specified TLS model for Var.
static TLSModel::Model getSelectedTLSModel(const GlobalVariable *Var) {
switch (Var->getThreadLocalMode()) {
case GlobalVariable::NotThreadLocal:
llvm_unreachable("getSelectedTLSModel for non-TLS variable");
break;
case GlobalVariable::GeneralDynamicTLSModel:
return TLSModel::GeneralDynamic;
case GlobalVariable::LocalDynamicTLSModel:
return TLSModel::LocalDynamic;
case GlobalVariable::InitialExecTLSModel:
return TLSModel::InitialExec;
case GlobalVariable::LocalExecTLSModel:
return TLSModel::LocalExec;
}
llvm_unreachable("invalid TLS model");
}
TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
// If GV is an alias then use the aliasee for determining
// thread-localness.
@@ -86,22 +104,31 @@ TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
bool isLocal = Var->hasLocalLinkage();
bool isDeclaration = Var->isDeclaration();
bool isPIC = getRelocationModel() == Reloc::PIC_;
bool isPIE = Options.PositionIndependentExecutable;
// FIXME: what should we do for protected and internal visibility?
// For variables, is internal different from hidden?
bool isHidden = Var->hasHiddenVisibility();
if (getRelocationModel() == Reloc::PIC_ &&
!Options.PositionIndependentExecutable) {
TLSModel::Model Model;
if (isPIC && !isPIE) {
if (isLocal || isHidden)
return TLSModel::LocalDynamic;
Model = TLSModel::LocalDynamic;
else
return TLSModel::GeneralDynamic;
Model = TLSModel::GeneralDynamic;
} else {
if (!isDeclaration || isHidden)
return TLSModel::LocalExec;
Model = TLSModel::LocalExec;
else
return TLSModel::InitialExec;
Model = TLSModel::InitialExec;
}
// If the user specified a more specific model, use that.
TLSModel::Model SelectedModel = getSelectedTLSModel(Var);
if (SelectedModel > Model)
return SelectedModel;
return Model;
}
/// getOptLevel - Returns the optimization level: None, Less,
@@ -135,4 +162,3 @@ void TargetMachine::setFunctionSections(bool V) {
void TargetMachine::setDataSections(bool V) {
DataSections = V;
}