1193323Sed//===-- TargetMachine.cpp - General Target Information ---------------------==//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file describes the general parts of a Target machine.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14249423Sdim#include "llvm/Target/TargetMachine.h"
15249423Sdim#include "llvm/CodeGen/MachineFunction.h"
16249423Sdim#include "llvm/IR/Function.h"
17249423Sdim#include "llvm/IR/GlobalAlias.h"
18249423Sdim#include "llvm/IR/GlobalValue.h"
19249423Sdim#include "llvm/IR/GlobalVariable.h"
20198090Srdivacky#include "llvm/MC/MCAsmInfo.h"
21234353Sdim#include "llvm/MC/MCCodeGenInfo.h"
22193323Sed#include "llvm/Support/CommandLine.h"
23193323Sedusing namespace llvm;
24193323Sed
25193323Sed//---------------------------------------------------------------------------
26193323Sed// Command-line options that tend to be useful on more than one back-end.
27193323Sed//
28193323Sed
29193323Sednamespace llvm {
30221345Sdim  bool HasDivModLibcall;
31193323Sed  bool AsmVerbosityDefault(false);
32193323Sed}
33193323Sed
34207618Srdivackystatic cl::opt<bool>
35207618SrdivackyDataSections("fdata-sections",
36207618Srdivacky  cl::desc("Emit data into separate sections"),
37207618Srdivacky  cl::init(false));
38207618Srdivackystatic cl::opt<bool>
39207618SrdivackyFunctionSections("ffunction-sections",
40207618Srdivacky  cl::desc("Emit functions into separate sections"),
41207618Srdivacky  cl::init(false));
42234353Sdim
43193323Sed//---------------------------------------------------------------------------
44193323Sed// TargetMachine Class
45193323Sed//
46193323Sed
47224145SdimTargetMachine::TargetMachine(const Target &T,
48234353Sdim                             StringRef TT, StringRef CPU, StringRef FS,
49234353Sdim                             const TargetOptions &Options)
50226633Sdim  : TheTarget(T), TargetTriple(TT), TargetCPU(CPU), TargetFS(FS),
51226633Sdim    CodeGenInfo(0), AsmInfo(0),
52218893Sdim    MCRelaxAll(false),
53218893Sdim    MCNoExecStack(false),
54221345Sdim    MCSaveTempLabels(false),
55221345Sdim    MCUseLoc(true),
56234353Sdim    MCUseCFI(true),
57234353Sdim    MCUseDwarfDirectory(false),
58234353Sdim    Options(Options) {
59194178Sed}
60194178Sed
61193323SedTargetMachine::~TargetMachine() {
62226633Sdim  delete CodeGenInfo;
63193323Sed  delete AsmInfo;
64193323Sed}
65193323Sed
66249423Sdim/// \brief Reset the target options based on the function's attributes.
67249423Sdimvoid TargetMachine::resetTargetOptions(const MachineFunction *MF) const {
68249423Sdim  const Function *F = MF->getFunction();
69249423Sdim  TargetOptions &TO = MF->getTarget().Options;
70249423Sdim
71249423Sdim#define RESET_OPTION(X, Y)                                              \
72249423Sdim  do {                                                                  \
73249423Sdim    if (F->hasFnAttribute(Y))                                           \
74249423Sdim      TO.X =                                                            \
75249423Sdim        (F->getAttributes().                                            \
76249423Sdim           getAttribute(AttributeSet::FunctionIndex,                    \
77249423Sdim                        Y).getValueAsString() == "true");               \
78249423Sdim  } while (0)
79249423Sdim
80249423Sdim  RESET_OPTION(NoFramePointerElim, "no-frame-pointer-elim");
81249423Sdim  RESET_OPTION(LessPreciseFPMADOption, "less-precise-fpmad");
82249423Sdim  RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
83249423Sdim  RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
84249423Sdim  RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
85249423Sdim  RESET_OPTION(UseSoftFloat, "use-soft-float");
86249423Sdim  RESET_OPTION(DisableTailCalls, "disable-tail-calls");
87249423Sdim}
88249423Sdim
89193323Sed/// getRelocationModel - Returns the code generation relocation model. The
90193323Sed/// choices are static, PIC, and dynamic-no-pic, and target default.
91226633SdimReloc::Model TargetMachine::getRelocationModel() const {
92226633Sdim  if (!CodeGenInfo)
93226633Sdim    return Reloc::Default;
94226633Sdim  return CodeGenInfo->getRelocationModel();
95193323Sed}
96193323Sed
97193323Sed/// getCodeModel - Returns the code model. The choices are small, kernel,
98193323Sed/// medium, large, and target default.
99226633SdimCodeModel::Model TargetMachine::getCodeModel() const {
100226633Sdim  if (!CodeGenInfo)
101226633Sdim    return CodeModel::Default;
102226633Sdim  return CodeGenInfo->getCodeModel();
103193323Sed}
104193323Sed
105239462Sdim/// Get the IR-specified TLS model for Var.
106239462Sdimstatic TLSModel::Model getSelectedTLSModel(const GlobalVariable *Var) {
107239462Sdim  switch (Var->getThreadLocalMode()) {
108239462Sdim  case GlobalVariable::NotThreadLocal:
109239462Sdim    llvm_unreachable("getSelectedTLSModel for non-TLS variable");
110239462Sdim    break;
111239462Sdim  case GlobalVariable::GeneralDynamicTLSModel:
112239462Sdim    return TLSModel::GeneralDynamic;
113239462Sdim  case GlobalVariable::LocalDynamicTLSModel:
114239462Sdim    return TLSModel::LocalDynamic;
115239462Sdim  case GlobalVariable::InitialExecTLSModel:
116239462Sdim    return TLSModel::InitialExec;
117239462Sdim  case GlobalVariable::LocalExecTLSModel:
118239462Sdim    return TLSModel::LocalExec;
119239462Sdim  }
120239462Sdim  llvm_unreachable("invalid TLS model");
121239462Sdim}
122239462Sdim
123234353SdimTLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
124239462Sdim  // If GV is an alias then use the aliasee for determining
125239462Sdim  // thread-localness.
126239462Sdim  if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
127239462Sdim    GV = GA->resolveAliasedGlobal(false);
128239462Sdim  const GlobalVariable *Var = cast<GlobalVariable>(GV);
129239462Sdim
130239462Sdim  bool isLocal = Var->hasLocalLinkage();
131239462Sdim  bool isDeclaration = Var->isDeclaration();
132239462Sdim  bool isPIC = getRelocationModel() == Reloc::PIC_;
133239462Sdim  bool isPIE = Options.PositionIndependentExecutable;
134234353Sdim  // FIXME: what should we do for protected and internal visibility?
135234353Sdim  // For variables, is internal different from hidden?
136239462Sdim  bool isHidden = Var->hasHiddenVisibility();
137234353Sdim
138239462Sdim  TLSModel::Model Model;
139239462Sdim  if (isPIC && !isPIE) {
140234353Sdim    if (isLocal || isHidden)
141239462Sdim      Model = TLSModel::LocalDynamic;
142234353Sdim    else
143239462Sdim      Model = TLSModel::GeneralDynamic;
144234353Sdim  } else {
145234353Sdim    if (!isDeclaration || isHidden)
146239462Sdim      Model = TLSModel::LocalExec;
147234353Sdim    else
148239462Sdim      Model = TLSModel::InitialExec;
149234353Sdim  }
150239462Sdim
151239462Sdim  // If the user specified a more specific model, use that.
152239462Sdim  TLSModel::Model SelectedModel = getSelectedTLSModel(Var);
153239462Sdim  if (SelectedModel > Model)
154239462Sdim    return SelectedModel;
155239462Sdim
156239462Sdim  return Model;
157234353Sdim}
158234353Sdim
159234353Sdim/// getOptLevel - Returns the optimization level: None, Less,
160234353Sdim/// Default, or Aggressive.
161234353SdimCodeGenOpt::Level TargetMachine::getOptLevel() const {
162234353Sdim  if (!CodeGenInfo)
163234353Sdim    return CodeGenOpt::Default;
164234353Sdim  return CodeGenInfo->getOptLevel();
165234353Sdim}
166234353Sdim
167263508Sdimvoid TargetMachine::setOptLevel(CodeGenOpt::Level Level) const {
168263508Sdim  if (CodeGenInfo)
169263508Sdim    CodeGenInfo->setOptLevel(Level);
170263508Sdim}
171263508Sdim
172193323Sedbool TargetMachine::getAsmVerbosityDefault() {
173193323Sed  return AsmVerbosityDefault;
174193323Sed}
175193323Sed
176193323Sedvoid TargetMachine::setAsmVerbosityDefault(bool V) {
177193323Sed  AsmVerbosityDefault = V;
178193323Sed}
179193323Sed
180207618Srdivackybool TargetMachine::getFunctionSections() {
181207618Srdivacky  return FunctionSections;
182207618Srdivacky}
183207618Srdivacky
184207618Srdivackybool TargetMachine::getDataSections() {
185207618Srdivacky  return DataSections;
186207618Srdivacky}
187207618Srdivacky
188207618Srdivackyvoid TargetMachine::setFunctionSections(bool V) {
189207618Srdivacky  FunctionSections = V;
190207618Srdivacky}
191207618Srdivacky
192207618Srdivackyvoid TargetMachine::setDataSections(bool V) {
193207618Srdivacky  DataSections = V;
194207618Srdivacky}
195