mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-24 23:28:41 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user