Coverage Report

Created: 2022-01-18 06:27

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