109c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo/* 209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * Copyright 2015, The Android Open Source Project 309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * 409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * Licensed under the Apache License, Version 2.0 (the "License"); 509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * you may not use this file except in compliance with the License. 609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * You may obtain a copy of the License at 709c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * 809c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * http://www.apache.org/licenses/LICENSE-2.0 909c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * 1009c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * Unless required by applicable law or agreed to in writing, software 1109c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * distributed under the License is distributed on an "AS IS" BASIS, 1209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * See the License for the specific language governing permissions and 1409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * limitations under the License. 1509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo */ 1609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 17a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Assert.h" 18a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Log.h" 19a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "RSTransforms.h" 20a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet 219d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo#include "bcinfo/MetadataExtractor.h" 2209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 23a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include <string> 24a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet 2509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo#include <llvm/Pass.h> 2609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo#include <llvm/IR/DIBuilder.h> 2709c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo#include <llvm/IR/Function.h> 2809c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo#include <llvm/IR/InstIterator.h> 2909c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo#include <llvm/IR/Instructions.h> 309d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo#include <llvm/IR/IRBuilder.h> 3109c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo#include <llvm/IR/Module.h> 320464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond#include <llvm/ADT/SetVector.h> 3309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 3409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leonamespace { 3509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 3609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leoconst char DEBUG_SOURCE_PATH[] = "/opt/renderscriptdebugger/1"; 3709c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leoconst char DEBUG_GENERATED_FILE[] = "generated.rs"; 389d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leoconst char DEBUG_PROTOTYPE_VAR_NAME[] = "rsDebugOuterForeachT"; 399d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leoconst char DEBUG_COMPILE_UNIT_MDNAME[] = "llvm.dbg.cu"; 4009c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 4109c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo/* 4209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * LLVM pass to attach debug information to the bits of code 4309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo * generated by the compiler. 4409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo */ 4509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leoclass RSAddDebugInfoPass : public llvm::ModulePass { 4609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 4709c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leopublic: 4809c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo // Pass ID 4909c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo static char ID; 5009c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 519d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo RSAddDebugInfoPass() : ModulePass(ID), kernelTypeMD(nullptr), 529d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo sourceFileName(nullptr), emptyExpr(nullptr), abiMetaCU(nullptr), 539d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo indexVarType(nullptr) { 5409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo } 5509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 5609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo virtual bool runOnModule(llvm::Module &Module) { 579d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Gather information about this bcc module. 589d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo bcinfo::MetadataExtractor me(&Module); 599d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (!me.extract()) { 609d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo ALOGE("Could not extract metadata from module!"); 619d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo return false; 629d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 639d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 640464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond const size_t nForEachKernels = me.getExportForEachSignatureCount(); 659d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo const char **forEachKernels = me.getExportForEachNameList(); 660464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond const bcinfo::MetadataExtractor::Reduce *reductions = 670464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond me.getExportReduceList(); 680464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond const size_t nReductions = me.getExportReduceCount(); 690464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond 700464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond llvm::SmallSetVector<llvm::Function *, 16> expandFuncs{}; 710464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond auto pushExpanded = [&](const char *const name) -> void { 720464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond bccAssert(name && *name && (::strcmp(name, ".") != 0)); 730464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond 740464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond const std::string expandName = std::string(name) + ".expand"; 750464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond if (llvm::Function *const func = Module.getFunction(expandName)) 760464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond expandFuncs.insert(func); 770464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond }; 780464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond 790464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond for (size_t i = 0; i < nForEachKernels; ++i) 800464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond pushExpanded(forEachKernels[i]); 810464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond 820464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond for (size_t i = 0; i < nReductions; ++i) { 830464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond const bcinfo::MetadataExtractor::Reduce &reduction = reductions[i]; 840464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond pushExpanded(reduction.mAccumulatorName); 850464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond } 869d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 8709c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo // Set up the debug info builder. 8809c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo llvm::DIBuilder DebugInfo(Module); 899d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo initializeDebugInfo(DebugInfo, Module); 9009c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 910464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond for (const auto &expandFunc : expandFuncs) { 920464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond // Attach DI metadata to each generated function. 930464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond // No inlining has occurred at this point so it's safe to name match 940464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond // without worrying about inlined function bodies. 950464789e86c9aa9a7f99762bd724444430bd86a7Luke Drummond attachDebugInfo(DebugInfo, *expandFunc); 969d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 9709c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 9809c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo DebugInfo.finalize(); 9909c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 1009d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo cleanupDebugInfo(Module); 1019d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 10209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo return true; 10309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo } 10409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 10509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leoprivate: 10609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 1079d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // @brief Initialize the debug info generation. 1089d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // 1099d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // This method does a couple of things: 1109d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // * Look up debug metadata for kernel ABI and store it if present. 1119d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // * Store a couple of useful pieces of debug metadata in member 1129d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // variables so they do not have to be created multiple times. 1139d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo void initializeDebugInfo(llvm::DIBuilder &DebugInfo, 1149d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo const llvm::Module &Module) { 1159d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::LLVMContext &ctx = Module.getContext(); 1169d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 1179d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Start generating debug information for bcc-generated code. 1180c5cfaeeb30135efe5e21d1aa9c858965c3019a6Ewan Crawford DebugInfo.createCompileUnit(llvm::dwarf::DW_LANG_GOOGLE_RenderScript, 1199d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo DEBUG_GENERATED_FILE, DEBUG_SOURCE_PATH, 1209d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo "RS", false, "", 0); 1219d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 1229d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Pre-generate and save useful pieces of debug metadata. 1239d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo sourceFileName = DebugInfo.createFile(DEBUG_GENERATED_FILE, DEBUG_SOURCE_PATH); 1249d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo emptyExpr = DebugInfo.createExpression(); 1259d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 1269d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Lookup compile unit with kernel ABI debug metadata. 1279d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::NamedMDNode *mdCompileUnitList = 1289d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo Module.getNamedMetadata(DEBUG_COMPILE_UNIT_MDNAME); 1299d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo bccAssert(mdCompileUnitList != nullptr && 1309d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo "DebugInfo pass could not find any existing compile units."); 1319d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 1329d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DIGlobalVariable *kernelPrototypeVarMD = nullptr; 1339d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo for (llvm::MDNode* CUNode : mdCompileUnitList->operands()) { 1349d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (auto *CU = llvm::dyn_cast<llvm::DICompileUnit>(CUNode)) { 1359d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo for (llvm::DIGlobalVariable* GV : CU->getGlobalVariables()) { 1369d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (GV->getDisplayName() == DEBUG_PROTOTYPE_VAR_NAME) { 1379d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo kernelPrototypeVarMD = GV; 1389d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo abiMetaCU = CU; 1399d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo break; 1409d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 1419d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 1429d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (kernelPrototypeVarMD != nullptr) 1439d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo break; 1449d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 1459d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 1469d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 1479d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Lookup the expanded function interface type metadata. 1489d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::MDTuple *kernelPrototypeMD = nullptr; 1499d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (kernelPrototypeVarMD != nullptr) { 1509d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Dig into the metadata to look for function prototype. 1519d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DIDerivedType *DT = nullptr; 1529d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo DT = llvm::cast<llvm::DIDerivedType>(kernelPrototypeVarMD->getType()); 1539d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo DT = llvm::cast<llvm::DIDerivedType>(DT->getBaseType()); 1549d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DISubroutineType *ST = llvm::cast<llvm::DISubroutineType>(DT->getBaseType()); 1559d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo kernelPrototypeMD = llvm::cast<llvm::MDTuple>(ST->getRawTypeArray()); 1569d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 1579d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo indexVarType = llvm::dyn_cast_or_null<llvm::DIType>( 1589d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo kernelPrototypeMD->getOperand(2)); 1599d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 1609d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Fall back to the function type of void() if there is no proper debug info. 1619d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (kernelPrototypeMD == nullptr) 1629d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo kernelPrototypeMD = llvm::MDTuple::get(ctx, {nullptr}); 1639d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Fall back to unspecified type if we don't have a proper index type. 1649d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (indexVarType == nullptr) 1659d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo indexVarType = DebugInfo.createBasicType("uint32_t", 32, 32, 1669d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::dwarf::DW_ATE_unsigned); 1679d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 1689d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Capture the expanded kernel type debug info. 169f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar kernelTypeMD = DebugInfo.createSubroutineType(kernelPrototypeMD); 1709d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 1719d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 17209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo /// @brief Add debug information to a generated function. 17309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo /// 1749d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo /// This procedure adds the following pieces of debug information 1759d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo /// to the function specified by Func: 1769d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo /// * Entry for the function to the current compile unit. 1779d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo /// * Adds debug info entries for each function argument. 1789d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo /// * Adds debug info entry for the rsIndex local variable. 1799d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo /// * File/line information to each instruction set to generates.rs:1. 18009c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo void attachDebugInfo(llvm::DIBuilder &DebugInfo, llvm::Function &Func) { 1819d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Lookup the current thread coordinate variable. 1829d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::AllocaInst* indexVar = nullptr; 183f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar for (llvm::Instruction &inst : llvm::instructions(Func)) { 1849d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (auto *allocaInst = llvm::dyn_cast<llvm::AllocaInst>(&inst)) { 1859d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (allocaInst->getName() == bcc::BCC_INDEX_VAR_NAME) { 1869d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo indexVar = allocaInst; 1879d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo break; 1889d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 1899d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 1909d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 19109c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 19209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo // Create function-level debug metadata. 1939d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DISubprogram *ExpandedFunc = DebugInfo.createFunction( 19409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo sourceFileName, // scope 19509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo Func.getName(), Func.getName(), 1969d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo sourceFileName, 1, kernelTypeMD, 197f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar false, true, 1, 0, false 19809c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo ); 1993ca8fe934c6147f486dbb346fea9ec14ada97daeDean De Leo Func.setSubprogram(ExpandedFunc); 20009c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 2019d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // IRBuilder for allocating variables for arguments. 202f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar llvm::IRBuilder<> ir(&*Func.getEntryBlock().begin()); 2039d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 2049d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Walk through the argument list and expanded function prototype 2059d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // debuginfo in lockstep to create debug entries for 2069d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // the expanded function arguments. 2079d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo unsigned argIdx = 1; 2089d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::MDTuple *argTypes = kernelTypeMD->getTypeArray().get(); 2099d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo for (llvm::Argument &arg : Func.getArgumentList()) { 2109d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Stop processing arguments if we run out of debug info. 2119d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (argIdx >= argTypes->getNumOperands()) 2129d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo break; 2139d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 2149d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Create debuginfo entry for the argument and advance. 215f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar llvm::DILocalVariable *argVarDI = DebugInfo.createParameterVariable( 216f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar ExpandedFunc, arg.getName(), argIdx, sourceFileName, 1, 2179d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::cast<llvm::DIType>(argTypes->getOperand(argIdx).get()), 218f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar true, 0 219f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar ); 2209d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 2219d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Annotate the argument variable in the IR. 2229d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::AllocaInst *argVar = 2239d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo ir.CreateAlloca(arg.getType(), nullptr, arg.getName() + ".var"); 2249d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::StoreInst *argStore = ir.CreateStore(&arg, argVar); 2259d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::LoadInst *loadedVar = ir.CreateLoad(argVar, arg.getName() + ".l"); 2269d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo DebugInfo.insertDeclare(argVar, argVarDI, emptyExpr, 2279d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DebugLoc::get(1, 1, ExpandedFunc), loadedVar); 2289d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo for (llvm::Use &u : arg.uses()) 2299d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (u.getUser() != argStore) 2309d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo u.set(loadedVar); 2319d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo argIdx++; 2329d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 2339d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 2349d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Annotate the index variable with metadata. 2359d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (indexVar) { 2369d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Debug information for loop index variable. 237f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar llvm::DILocalVariable *indexVarDI = DebugInfo.createAutoVariable( 238f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar ExpandedFunc, bcc::BCC_INDEX_VAR_NAME, sourceFileName, 1, 239f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar indexVarType, true 240f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar ); 2419d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 2429d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Insert declaration annotation in the instruction stream. 2439d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::Instruction *decl = DebugInfo.insertDeclare( 2449d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo indexVar, indexVarDI, emptyExpr, 2459d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DebugLoc::get(1, 1, ExpandedFunc), indexVar); 2469d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo indexVar->moveBefore(decl); 2479d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 2489d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 2499d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Attach location information to each instruction in the function. 250f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar for (llvm::Instruction &inst : llvm::instructions(Func)) { 2519d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo inst.setDebugLoc(llvm::DebugLoc::get(1, 1, ExpandedFunc)); 25209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo } 25309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo } 25409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 2559d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // @brief Clean up the debug info. 2569d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // 2579d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // At the moment, it only finds the compile unit for the expanded function 2589d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // metadata generated by clang and removes it. 2599d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo void cleanupDebugInfo(llvm::Module& Module) { 2609d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (abiMetaCU == nullptr) 2619d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo return; 2629d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 2639d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // Remove the compile unit with the runtime interface DI. 2649d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::SmallVector<llvm::MDNode*, 4> unitsTmp; 2659d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::NamedMDNode *debugMD = 2669d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo Module.getNamedMetadata(DEBUG_COMPILE_UNIT_MDNAME); 2679d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo for (llvm::MDNode *cu : debugMD->operands()) 2689d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo if (cu != abiMetaCU) 2699d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo unitsTmp.push_back(cu); 2709d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo debugMD->eraseFromParent(); 2719d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo debugMD = Module.getOrInsertNamedMetadata(DEBUG_COMPILE_UNIT_MDNAME); 2729d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo for (llvm::MDNode *cu : unitsTmp) 2739d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo debugMD->addOperand(cu); 2749d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo } 2759d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 2769d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leoprivate: 2779d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo // private attributes 2789d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DISubroutineType* kernelTypeMD; 2799d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DIFile *sourceFileName; 2809d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DIExpression *emptyExpr; 2819d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DICompileUnit *abiMetaCU; 2829d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo llvm::DIType *indexVarType; 2839d009b0a25bf7eea6f2da2521107dc37acea9accDean De Leo 28409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo}; // end class RSAddDebugInfoPass 28509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 28609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leochar RSAddDebugInfoPass::ID = 0; 28709c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leostatic llvm::RegisterPass<RSAddDebugInfoPass> X("addrsdi", "Add RS DebugInfo Pass"); 28809c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 28909c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo} // end anonymous namespace 29009c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 29109c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leonamespace bcc { 29209c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 29309c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leollvm::ModulePass * createRSAddDebugInfoPass() { 29409c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo return new RSAddDebugInfoPass(); 29509c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo} 29609c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo 29709c7a41f73602bec33e9d392cc959d78931f73c4Dean De Leo} // end namespace bcc 298