aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2016-01-30 22:35:16 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-01-30 22:35:16 +0000
commitf0bc959d8d2397fedc45ba5b283cf6b4cd274ea4 (patch)
tree54dfbd54a20d56cc5a5fe77e8231fc39569c1276
parent84ec850611f0cca36176b6aa76cfc6ed6ce8650a (diff)
parent09c7a41f73602bec33e9d392cc959d78931f73c4 (diff)
downloadlibbcc-f0bc959d8d2397fedc45ba5b283cf6b4cd274ea4.tar.gz
Merge "Initial version of debug info pass for RS."
-rw-r--r--include/bcc/Compiler.h1
-rw-r--r--include/bcc/Renderscript/RSTransforms.h2
-rw-r--r--include/bcc/Source.h4
-rw-r--r--lib/Core/Compiler.cpp6
-rw-r--r--lib/Core/Source.cpp4
-rw-r--r--lib/Renderscript/Android.mk1
-rw-r--r--lib/Renderscript/RSAddDebugInfoPass.cpp112
7 files changed, 130 insertions, 0 deletions
diff --git a/include/bcc/Compiler.h b/include/bcc/Compiler.h
index 8a30c38..a0925b8 100644
--- a/include/bcc/Compiler.h
+++ b/include/bcc/Compiler.h
@@ -82,6 +82,7 @@ private:
bool addInternalizeSymbolsPass(Script &pScript, llvm::legacy::PassManager &pPM);
void addExpandKernelPass(llvm::legacy::PassManager &pPM);
+ void addDebugInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
void addGlobalInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
void addInvariantPass(llvm::legacy::PassManager &pPM);
void addInvokeHelperPass(llvm::legacy::PassManager &pPM);
diff --git a/include/bcc/Renderscript/RSTransforms.h b/include/bcc/Renderscript/RSTransforms.h
index 6dcfedd..3c81860 100644
--- a/include/bcc/Renderscript/RSTransforms.h
+++ b/include/bcc/Renderscript/RSTransforms.h
@@ -43,6 +43,8 @@ llvm::ModulePass * createRSIsThreadablePass();
llvm::ModulePass * createRSX86_64CallConvPass();
+llvm::ModulePass * createRSAddDebugInfoPass();
+
} // end namespace bcc
#endif // BCC_RS_TRANSFORMS_H
diff --git a/include/bcc/Source.h b/include/bcc/Source.h
index 54263a2..e6bef2e 100644
--- a/include/bcc/Source.h
+++ b/include/bcc/Source.h
@@ -82,6 +82,10 @@ public:
void addBuildChecksumMetadata(const char *) const;
+ // Get whether debugging has been enabled for this module by checking
+ // for presence of debug info in the module.
+ bool getDebugInfoEnabled() const;
+
~Source();
};
diff --git a/lib/Core/Compiler.cpp b/lib/Core/Compiler.cpp
index eea0750..35f19d7 100644
--- a/lib/Core/Compiler.cpp
+++ b/lib/Core/Compiler.cpp
@@ -159,6 +159,7 @@ enum Compiler::ErrorCode Compiler::runPasses(Script &pScript,
// Add some initial custom passes.
addInvokeHelperPass(transformPasses);
addExpandKernelPass(transformPasses);
+ addDebugInfoPass(pScript, transformPasses);
addInvariantPass(transformPasses);
if (!addInternalizeSymbolsPass(pScript, transformPasses))
return kErrCustomPasses;
@@ -387,6 +388,11 @@ void Compiler::addInvokeHelperPass(llvm::legacy::PassManager &pPM) {
}
}
+void Compiler::addDebugInfoPass(Script &pScript, llvm::legacy::PassManager &pPM) {
+ if (pScript.getSource().getDebugInfoEnabled())
+ pPM.add(createRSAddDebugInfoPass());
+}
+
void Compiler::addExpandKernelPass(llvm::legacy::PassManager &pPM) {
// Expand ForEach and reduce on CPU path to reduce launch overhead.
bool pEnableStepOpt = true;
diff --git a/lib/Core/Source.cpp b/lib/Core/Source.cpp
index 94da98e..25b263f 100644
--- a/lib/Core/Source.cpp
+++ b/lib/Core/Source.cpp
@@ -181,4 +181,8 @@ void Source::addBuildChecksumMetadata(const char *buildChecksum) const {
node->addOperand(llvm::MDNode::get(context, val));
}
+bool Source::getDebugInfoEnabled() const {
+ return mModule->getNamedMetadata("llvm.dbg.cu") != nullptr;
+}
+
} // namespace bcc
diff --git a/lib/Renderscript/Android.mk b/lib/Renderscript/Android.mk
index 7744447..32e65b3 100644
--- a/lib/Renderscript/Android.mk
+++ b/lib/Renderscript/Android.mk
@@ -22,6 +22,7 @@ LOCAL_PATH := $(call my-dir)
#=====================================================================
libbcc_renderscript_SRC_FILES := \
+ RSAddDebugInfoPass.cpp \
RSCompilerDriver.cpp \
RSEmbedInfo.cpp \
RSKernelExpand.cpp \
diff --git a/lib/Renderscript/RSAddDebugInfoPass.cpp b/lib/Renderscript/RSAddDebugInfoPass.cpp
new file mode 100644
index 0000000..03ad24a
--- /dev/null
+++ b/lib/Renderscript/RSAddDebugInfoPass.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bcc/Assert.h"
+#include "bcc/Renderscript/RSTransforms.h"
+
+#include <llvm/Pass.h>
+#include <llvm/IR/DataLayout.h>
+#include <llvm/IR/DIBuilder.h>
+#include <llvm/IR/Function.h>
+#include <llvm/IR/Function.h>
+#include <llvm/IR/InstIterator.h>
+#include <llvm/IR/Instructions.h>
+#include <llvm/IR/MDBuilder.h>
+#include <llvm/IR/Module.h>
+#include <llvm/IR/Type.h>
+#include <llvm/Transforms/Utils/BasicBlockUtils.h>
+
+namespace {
+
+const char DEBUG_SOURCE_PATH[] = "/opt/renderscriptdebugger/1";
+const char DEBUG_GENERATED_FILE[] = "generated.rs";
+
+/*
+ * LLVM pass to attach debug information to the bits of code
+ * generated by the compiler.
+ */
+class RSAddDebugInfoPass : public llvm::ModulePass {
+
+public:
+ // Pass ID
+ static char ID;
+
+ RSAddDebugInfoPass() : ModulePass(ID) {
+ }
+
+ virtual bool runOnModule(llvm::Module &Module) {
+ // Set up the debug info builder.
+ llvm::DIBuilder DebugInfo(Module);
+ DebugInfo.createCompileUnit(llvm::dwarf::DW_LANG_C99,
+ DEBUG_GENERATED_FILE, DEBUG_SOURCE_PATH,
+ "RS", false, "", 0);
+
+ // Attach DI metadata to each generated function.
+ for (llvm::Function &Func : Module)
+ if (Func.getName().endswith(".expand"))
+ attachDebugInfo(DebugInfo, Func);
+
+ DebugInfo.finalize();
+
+ return true;
+ }
+
+private:
+
+ /// @brief Add debug information to a generated function.
+ ///
+ /// This function is used to attach source file and line information
+ /// to the generated function code.
+ void attachDebugInfo(llvm::DIBuilder &DebugInfo, llvm::Function &Func) {
+ llvm::DIFile *sourceFileName =
+ DebugInfo.createFile(DEBUG_GENERATED_FILE, DEBUG_SOURCE_PATH);
+
+ // Fabricated function type
+ llvm::MDTuple *nullMD = llvm::MDTuple::get(Func.getParent()->getContext(),
+ { DebugInfo.createUnspecifiedType("void") });
+
+ // Create function-level debug metadata.
+ llvm::DIScope *GeneratedScope = DebugInfo.createFunction(
+ sourceFileName, // scope
+ Func.getName(), Func.getName(),
+ sourceFileName, 1,
+ DebugInfo.createSubroutineType(sourceFileName, nullMD),
+ false, true, 1, 0, false, &Func
+ );
+
+ // Attach location inforamtion to each instruction in the function
+ for (llvm::inst_iterator Inst = llvm::inst_begin(Func),
+ InstEnd = llvm::inst_end(Func);
+ Inst != InstEnd;
+ ++Inst) {
+ Inst->setDebugLoc(llvm::DebugLoc::get(1, 1, GeneratedScope));
+ }
+ }
+
+}; // end class RSAddDebugInfoPass
+
+char RSAddDebugInfoPass::ID = 0;
+static llvm::RegisterPass<RSAddDebugInfoPass> X("addrsdi", "Add RS DebugInfo Pass");
+
+} // end anonymous namespace
+
+namespace bcc {
+
+llvm::ModulePass * createRSAddDebugInfoPass() {
+ return new RSAddDebugInfoPass();
+}
+
+} // end namespace bcc