]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / LanguageRuntime / RenderScript / RenderScriptRuntime / RenderScriptExpressionOpts.cpp
1 //===-- RenderScriptExpressionOpts.cpp --------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <string>
11
12 #include "llvm/ADT/None.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/IR/Instruction.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/LegacyPassManager.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/TargetRegistry.h"
19 #include "llvm/Target/TargetMachine.h"
20 #include "llvm/Target/TargetOptions.h"
21
22 #include "clang/Basic/TargetOptions.h"
23
24 #include "lldb/Target/Process.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Utility/Log.h"
27
28 #include "RenderScriptExpressionOpts.h"
29 #include "RenderScriptRuntime.h"
30 #include "RenderScriptx86ABIFixups.h"
31
32 using namespace lldb_private;
33 using namespace lldb_renderscript;
34
35 // [``slang``](https://android.googlesource.com/platform/frameworks/compile/slang),
36 // the compiler frontend for RenderScript embeds an ARM specific triple in IR
37 // that is shipped in the app, after generating IR that has some assumptions
38 // that an ARM device is the target. As the IR is then compiled on a device of
39 // unknown (at time the IR was generated at least) architecture, when calling
40 // RenderScript API function as part of debugger expressions, we have to
41 // perform a fixup pass that removes those assumptions right before the module
42 // is sent to be generated by the llvm backend.
43
44 namespace {
45 bool registerRSDefaultTargetOpts(clang::TargetOptions &proto,
46                                  const llvm::Triple::ArchType &arch) {
47   switch (arch) {
48   case llvm::Triple::ArchType::x86:
49     proto.Triple = "i686--linux-android";
50     proto.CPU = "atom";
51     proto.Features.push_back("+long64");
52     // Fallthrough for common x86 family features
53     LLVM_FALLTHROUGH;
54   case llvm::Triple::ArchType::x86_64:
55     proto.Features.push_back("+mmx");
56     proto.Features.push_back("+sse");
57     proto.Features.push_back("+sse2");
58     proto.Features.push_back("+sse3");
59     proto.Features.push_back("+ssse3");
60     proto.Features.push_back("+sse4.1");
61     proto.Features.push_back("+sse4.2");
62     break;
63   case llvm::Triple::ArchType::mipsel:
64     // pretend this is `arm' for the front-end
65     proto.Triple = "armv7-none-linux-android";
66     proto.CPU = "";
67     proto.Features.push_back("+long64");
68     break;
69   case llvm::Triple::ArchType::mips64el:
70     // pretend this is `aarch64' for the front-end
71     proto.Triple = "aarch64-none-linux-android";
72     proto.CPU = "";
73     break;
74   default:
75     return false;
76   }
77   return true;
78 }
79 } // end anonymous namespace
80
81 bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
82   bool changed_module = false;
83   Log *log(
84       GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_EXPRESSIONS));
85
86   std::string err;
87   llvm::StringRef real_triple =
88       m_process_ptr->GetTarget().GetArchitecture().GetTriple().getTriple();
89   const llvm::Target *target_info =
90       llvm::TargetRegistry::lookupTarget(real_triple, err);
91   if (!target_info) {
92     if (log)
93       log->Warning("couldn't determine real target architecture: '%s'",
94                    err.c_str());
95     return false;
96   }
97
98   llvm::Optional<llvm::Reloc::Model> reloc_model = llvm::None;
99   assert(m_process_ptr && "no available lldb process");
100   switch (m_process_ptr->GetTarget().GetArchitecture().GetMachine()) {
101   case llvm::Triple::ArchType::x86:
102     changed_module |= fixupX86FunctionCalls(module);
103     // For some reason this triple gets totally missed by the backend, and must
104     // be set manually. There a reference in bcc/Main.cpp about auto feature-
105     // detection being removed from LLVM3.5, but I can't see that discussion
106     // anywhere public.
107     real_triple = "i686--linux-android";
108     break;
109   case llvm::Triple::ArchType::x86_64:
110     changed_module |= fixupX86_64FunctionCalls(module);
111     break;
112   case llvm::Triple::ArchType::mipsel:
113   case llvm::Triple::ArchType::mips64el:
114     // No actual IR fixup pass is needed on MIPS, but the datalayout and
115     // targetmachine do need to be explicitly set.
116
117     // bcc explicitly compiles MIPS code to use the static relocation model due
118     // to an issue with relocations in mclinker. see
119     // libbcc/support/CompilerConfig.cpp for details
120     reloc_model = llvm::Reloc::Static;
121     changed_module = true;
122     break;
123   case llvm::Triple::ArchType::arm:
124   case llvm::Triple::ArchType::aarch64:
125     // ARM subtargets need no fixup passes as they are the initial target as
126     // generated by the
127     // slang compiler frontend.
128     break;
129   default:
130     if (log)
131       log->Warning("Ignoring unknown renderscript target");
132     return false;
133   }
134
135   if (changed_module) {
136     llvm::TargetOptions options;
137     llvm::TargetMachine *target_machine = target_info->createTargetMachine(
138         real_triple, "", "", options, reloc_model);
139     assert(target_machine &&
140            "failed to identify RenderScriptRuntime target machine");
141     // We've been using a triple and datalayout of some ARM variant all along,
142     // so we need to let the backend know that this is no longer the case.
143     if (log) {
144       log->Printf("%s - Changing RS target triple to '%s'", __FUNCTION__,
145                   real_triple.str().c_str());
146       log->Printf(
147           "%s - Changing RS datalayout to '%s'", __FUNCTION__,
148           target_machine->createDataLayout().getStringRepresentation().c_str());
149     }
150     module.setTargetTriple(real_triple);
151     module.setDataLayout(target_machine->createDataLayout());
152   }
153   return changed_module;
154 }
155
156 char RenderScriptRuntimeModulePass::ID = 0;
157
158 namespace lldb_private {
159
160 bool RenderScriptRuntime::GetOverrideExprOptions(clang::TargetOptions &proto) {
161   auto *process = GetProcess();
162   assert(process);
163   return registerRSDefaultTargetOpts(
164       proto, process->GetTarget().GetArchitecture().GetMachine());
165 }
166
167 bool RenderScriptRuntime::GetIRPasses(LLVMUserExpression::IRPasses &passes) {
168   if (!m_ir_passes)
169     m_ir_passes = new RSIRPasses(GetProcess());
170   assert(m_ir_passes);
171
172   passes.EarlyPasses = m_ir_passes->EarlyPasses;
173   passes.LatePasses = m_ir_passes->LatePasses;
174
175   return true;
176 }
177
178 namespace lldb_renderscript {
179
180 RSIRPasses::RSIRPasses(Process *process) {
181   IRPasses();
182   assert(process);
183
184   EarlyPasses = std::make_shared<llvm::legacy::PassManager>();
185   assert(EarlyPasses);
186   EarlyPasses->add(new RenderScriptRuntimeModulePass(process));
187 }
188
189 RSIRPasses::~RSIRPasses() {}
190
191 } // namespace lldb_renderscript
192 } // namespace lldb_private