1750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines/* 2750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * Copyright 2015, The Android Open Source Project 3750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * 4750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * you may not use this file except in compliance with the License. 6750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * You may obtain a copy of the License at 7750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * 8750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * 10750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * Unless required by applicable law or agreed to in writing, software 11750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * See the License for the specific language governing permissions and 14750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * limitations under the License. 15750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines */ 16750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 17a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Assert.h" 18a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Log.h" 19a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "RSUtils.h" 20750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 21fb81ec1a875d13d9750006313b9123903336101dStephen Hines#include "rsDefines.h" 22fb81ec1a875d13d9750006313b9123903336101dStephen Hines 23750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines#include <llvm/IR/Constant.h> 24750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines#include <llvm/IR/Constants.h> 25750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines#include <llvm/IR/Type.h> 26750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines#include <llvm/IR/Module.h> 27750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines#include <llvm/IR/Function.h> 28750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines#include <llvm/Pass.h> 29750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 30750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines#include <sstream> 31750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines#include <vector> 32750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 33750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hinesnamespace { 34750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 35fb81ec1a875d13d9750006313b9123903336101dStephen Hinesconst bool kDebugGlobalInfo = false; 36750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 37750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines/* RSGlobalInfoPass: Embeds additional information about RenderScript global 38fb81ec1a875d13d9750006313b9123903336101dStephen Hines * variables into the Module. The 5 variables added are specified as follows: 39750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * 1) .rs.global_entries 40750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * i32 - int 41750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * Optional number of global variables. 42750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * 2) .rs.global_names 43750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * [N * i8*] - const char *[N] 44750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * Optional global variable name info. Each entry corresponds to the name 45750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * of 1 of the N global variables. 46750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * 3) .rs.global_addresses 47750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * [N * i8*] - void*[N] or void** 48750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * Optional global variable address info. Each entry corresponds to the 49750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * address of 1 of the N global variables. 50750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * 4) .rs.global_sizes 51750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * [N * i32] or [N * i64] - size_t[N] 52750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * Optional global variable size info. Each entry corresponds to the size 53750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines * of 1 of the N global variables. 54fb81ec1a875d13d9750006313b9123903336101dStephen Hines * 5) .rs.global_properties 55fb81ec1a875d13d9750006313b9123903336101dStephen Hines * [N * i32] 56fb81ec1a875d13d9750006313b9123903336101dStephen Hines * Optional global properties. Each entry corresponds to the properties 57fb81ec1a875d13d9750006313b9123903336101dStephen Hines * for 1 of the N global variables. The 32-bit integer for properties 58fb81ec1a875d13d9750006313b9123903336101dStephen Hines * can be broken down as follows: 59fb81ec1a875d13d9750006313b9123903336101dStephen Hines * bit(s) Encoded value 60fb81ec1a875d13d9750006313b9123903336101dStephen Hines * ------ ------------- 61fb81ec1a875d13d9750006313b9123903336101dStephen Hines * 18 Pointer (1 is pointer, 0 is non-pointer) 62fb81ec1a875d13d9750006313b9123903336101dStephen Hines * 17 Static (1 is static, 0 is extern) 63fb81ec1a875d13d9750006313b9123903336101dStephen Hines * 16 Constant (1 is const, 0 is non-const) 64fb81ec1a875d13d9750006313b9123903336101dStephen Hines * 15 - 0 RsDataType (see frameworks/rs/rsDefines.h for more info) 65750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines */ 66750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hinesclass RSGlobalInfoPass: public llvm::ModulePass { 67750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hinesprivate: 68750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // If true, we don't include information about immutable global variables 69750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // in our various exported data structures. 70750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines bool mSkipConstants; 71750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 72fb81ec1a875d13d9750006313b9123903336101dStephen Hines // Encodes properties of the GlobalVariable into a uint32_t. 73fb81ec1a875d13d9750006313b9123903336101dStephen Hines // These values are used to populate the .rs.global_properties array. 74fb81ec1a875d13d9750006313b9123903336101dStephen Hines static uint32_t getEncodedProperties(const llvm::GlobalVariable &GV) { 75fb81ec1a875d13d9750006313b9123903336101dStephen Hines auto GlobalType = GV.getType()->getPointerElementType(); 76fb81ec1a875d13d9750006313b9123903336101dStephen Hines 77fb81ec1a875d13d9750006313b9123903336101dStephen Hines // We start by getting the RsDataType and placing it into our result. 78fb81ec1a875d13d9750006313b9123903336101dStephen Hines uint32_t result = getRsDataTypeForType(GlobalType); 79fb81ec1a875d13d9750006313b9123903336101dStephen Hines bccAssert(!(result & ~RS_GLOBAL_TYPE)); // Can only alter lower 16-bits. 80fb81ec1a875d13d9750006313b9123903336101dStephen Hines 81fb81ec1a875d13d9750006313b9123903336101dStephen Hines if (GlobalType->isPointerTy()) { 82fb81ec1a875d13d9750006313b9123903336101dStephen Hines // Global variables that are pointers can all be used with "bind". 83fb81ec1a875d13d9750006313b9123903336101dStephen Hines result |= RS_GLOBAL_POINTER; 84fb81ec1a875d13d9750006313b9123903336101dStephen Hines } 85fb81ec1a875d13d9750006313b9123903336101dStephen Hines 86fb81ec1a875d13d9750006313b9123903336101dStephen Hines if (GV.isConstant()) { 87fb81ec1a875d13d9750006313b9123903336101dStephen Hines result |= RS_GLOBAL_CONSTANT; 88fb81ec1a875d13d9750006313b9123903336101dStephen Hines } 89fb81ec1a875d13d9750006313b9123903336101dStephen Hines 90fb81ec1a875d13d9750006313b9123903336101dStephen Hines if (GV.getLinkage() == llvm::GlobalValue::InternalLinkage) { 91fb81ec1a875d13d9750006313b9123903336101dStephen Hines // We only have internal linkage in RS to signify static. 92fb81ec1a875d13d9750006313b9123903336101dStephen Hines result |= RS_GLOBAL_STATIC; 93fb81ec1a875d13d9750006313b9123903336101dStephen Hines } 94fb81ec1a875d13d9750006313b9123903336101dStephen Hines 95fb81ec1a875d13d9750006313b9123903336101dStephen Hines return result; 96fb81ec1a875d13d9750006313b9123903336101dStephen Hines } 97fb81ec1a875d13d9750006313b9123903336101dStephen Hines 98fb81ec1a875d13d9750006313b9123903336101dStephen Hinespublic: 99fb81ec1a875d13d9750006313b9123903336101dStephen Hines static char ID; 100fb81ec1a875d13d9750006313b9123903336101dStephen Hines 1017e920a716693033edf32a6fedd03798bbfbd85ebChih-Hung Hsieh explicit RSGlobalInfoPass(bool pSkipConstants = false) 102750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines : ModulePass (ID), mSkipConstants(pSkipConstants) { 103750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 104750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 105fb81ec1a875d13d9750006313b9123903336101dStephen Hines void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { 106750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // This pass does not use any other analysis passes, but it does 107750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // add new global variables. 108750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 109750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 110750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines bool runOnModule(llvm::Module &M) override { 111750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines std::vector<llvm::Constant *> GVAddresses; 112750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines std::vector<llvm::Constant *> GVNames; 113721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala std::vector<std::string> GVNameStrings; 114750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines std::vector<uint32_t> GVSizes32; 115750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines std::vector<uint64_t> GVSizes64; 116fb81ec1a875d13d9750006313b9123903336101dStephen Hines std::vector<uint32_t> GVProperties; 117750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 118750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines const llvm::DataLayout &DL = M.getDataLayout(); 119750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines const size_t PointerSizeInBits = DL.getPointerSizeInBits(); 120750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 121750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines bccAssert(PointerSizeInBits == 32 || PointerSizeInBits == 64); 122750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 123750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines int GlobalNumber = 0; 124750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 125721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala // i8* - LLVM uses this to represent void* and char* 126721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala llvm::Type *VoidPtrTy = llvm::Type::getInt8PtrTy(M.getContext()); 127721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala 128721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala // i32 129721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala llvm::Type *Int32Ty = llvm::Type::getInt32Ty(M.getContext()); 130721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala 131721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala // i32 or i64 depending on our actual size_t 132721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala llvm::Type *SizeTy = llvm::Type::getIntNTy(M.getContext(), 133721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala PointerSizeInBits); 134721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala 135750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines for (auto &GV : M.globals()) { 136750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // Skip constant variables if we were configured to do so. 137750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines if (mSkipConstants && GV.isConstant()) { 138750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines continue; 139750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 140750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 141e32af52d4be2bb80783404d99fa338b1143dbc9aDavid Gross // Skip intrinsic variables. 142e32af52d4be2bb80783404d99fa338b1143dbc9aDavid Gross if (GV.getName().startswith("llvm.")) { 143e32af52d4be2bb80783404d99fa338b1143dbc9aDavid Gross continue; 144e32af52d4be2bb80783404d99fa338b1143dbc9aDavid Gross } 145e32af52d4be2bb80783404d99fa338b1143dbc9aDavid Gross 146750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // In LLVM, an instance of GlobalVariable is actually a Value 147750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // corresponding to the address of it. 148721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala GVAddresses.push_back(llvm::ConstantExpr::getBitCast(&GV, VoidPtrTy)); 149721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala GVNameStrings.push_back(GV.getName()); 150750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 151750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // Since these are all global variables, their type is actually a 152750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // pointer to the underlying data. We can extract the total underlying 153750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // storage size by looking at the first contained type. 154fb81ec1a875d13d9750006313b9123903336101dStephen Hines auto GlobalType = GV.getType()->getPointerElementType(); 155fb81ec1a875d13d9750006313b9123903336101dStephen Hines auto TypeSize = DL.getTypeAllocSize(GlobalType); 156750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines if (PointerSizeInBits == 32) { 157750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GVSizes32.push_back(TypeSize); 158750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } else { 159750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GVSizes64.push_back(TypeSize); 160750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 161fb81ec1a875d13d9750006313b9123903336101dStephen Hines 162fb81ec1a875d13d9750006313b9123903336101dStephen Hines GVProperties.push_back(getEncodedProperties(GV)); 163750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 164750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 165750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // Create the new strings for storing the names of the global variables. 166750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // This has to be done as a separate pass (over the original global 167750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // variables), because these strings are new global variables themselves. 1688a019dd0040bedf5078e4d18e06a244a675b80e8Chih-Hung Hsieh for (const auto &GVN : GVNameStrings) { 169750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::Constant *C = 170721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala llvm::ConstantDataArray::getString(M.getContext(), GVN); 171750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines std::stringstream VarName; 172750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines VarName << ".rs.name_str_" << GlobalNumber++; 173750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::Value *V = M.getOrInsertGlobal(VarName.str(), C->getType()); 174750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::GlobalVariable *VarAsStr = llvm::dyn_cast<llvm::GlobalVariable>(V); 175750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines VarAsStr->setInitializer(C); 176750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines VarAsStr->setConstant(true); 177750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines VarAsStr->setLinkage(llvm::GlobalValue::PrivateLinkage); 178f5b49a0ca149b09c8306b86db9f3aca703c4acd5Pirama Arumuga Nainar VarAsStr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); 179721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala // VarAsStr has type [_ x i8]*. Cast to i8* for storing in 180721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala // .rs.global_names. 181721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala GVNames.push_back(llvm::ConstantExpr::getBitCast(VarAsStr, VoidPtrTy)); 182750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 183750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 184750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines if (PointerSizeInBits == 32) { 185750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines bccAssert(GVAddresses.size() == GVSizes32.size()); 186750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines bccAssert(GVSizes64.size() == 0); 187fb81ec1a875d13d9750006313b9123903336101dStephen Hines bccAssert(GVAddresses.size() == GVProperties.size()); 188750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } else { 189750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines bccAssert(GVSizes32.size() == 0); 190750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines bccAssert(GVAddresses.size() == GVSizes64.size()); 191fb81ec1a875d13d9750006313b9123903336101dStephen Hines bccAssert(GVAddresses.size() == GVProperties.size()); 192750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 193750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 194721414ca0d1f1d6a1f98b5f16c5766cfa001d784Matt Wala size_t NumGlobals = GVAddresses.size(); 195750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 196750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // [NumGlobals * i8*] 197750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::ArrayType *VoidPtrArrayTy = llvm::ArrayType::get(VoidPtrTy, 198750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines NumGlobals); 199750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // [NumGlobals * i32] or [NumGlobals * i64] 200750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::ArrayType *SizeArrayTy = llvm::ArrayType::get(SizeTy, NumGlobals); 201750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 202fb81ec1a875d13d9750006313b9123903336101dStephen Hines // [NumGlobals * i32] 203fb81ec1a875d13d9750006313b9123903336101dStephen Hines llvm::ArrayType *Int32ArrayTy = llvm::ArrayType::get(Int32Ty, NumGlobals); 204fb81ec1a875d13d9750006313b9123903336101dStephen Hines 205750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // 1) @.rs.global_entries = constant i32 NumGlobals 206fb81ec1a875d13d9750006313b9123903336101dStephen Hines llvm::Value *V = M.getOrInsertGlobal(kRsGlobalEntries, Int32Ty); 207750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::GlobalVariable *GlobalEntries = 208750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::dyn_cast<llvm::GlobalVariable>(V); 209750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::Constant *GlobalEntriesInit = 210750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::ConstantInt::get(Int32Ty, NumGlobals); 211750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalEntries->setInitializer(GlobalEntriesInit); 212750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalEntries->setConstant(true); 213750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 214750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // 2) @.rs.global_names = constant [N * i8*] [...] 215fb81ec1a875d13d9750006313b9123903336101dStephen Hines V = M.getOrInsertGlobal(kRsGlobalNames, VoidPtrArrayTy); 216750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::GlobalVariable *GlobalNames = 217750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::dyn_cast<llvm::GlobalVariable>(V); 218750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::Constant *GlobalNamesInit = 219750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::ConstantArray::get(VoidPtrArrayTy, GVNames); 220750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalNames->setInitializer(GlobalNamesInit); 221750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalNames->setConstant(true); 222750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 223750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // 3) @.rs.global_addresses = constant [N * i8*] [...] 224fb81ec1a875d13d9750006313b9123903336101dStephen Hines V = M.getOrInsertGlobal(kRsGlobalAddresses, VoidPtrArrayTy); 225750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::GlobalVariable *GlobalAddresses = 226750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::dyn_cast<llvm::GlobalVariable>(V); 227750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::Constant *GlobalAddressesInit = 228750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::ConstantArray::get(VoidPtrArrayTy, GVAddresses); 229750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalAddresses->setInitializer(GlobalAddressesInit); 230750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalAddresses->setConstant(true); 231750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 232750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 233750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // 4) @.rs.global_sizes = constant [N * i32 or i64] [...] 234fb81ec1a875d13d9750006313b9123903336101dStephen Hines V = M.getOrInsertGlobal(kRsGlobalSizes, SizeArrayTy); 235750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::GlobalVariable *GlobalSizes = 236750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::dyn_cast<llvm::GlobalVariable>(V); 237750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines llvm::Constant *GlobalSizesInit; 238750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines if (PointerSizeInBits == 32) { 239750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalSizesInit = llvm::ConstantDataArray::get(M.getContext(), GVSizes32); 240750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } else { 241750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalSizesInit = llvm::ConstantDataArray::get(M.getContext(), GVSizes64); 242750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 243750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalSizes->setInitializer(GlobalSizesInit); 244750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalSizes->setConstant(true); 245750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 246fb81ec1a875d13d9750006313b9123903336101dStephen Hines // 5) @.rs.global_properties = constant i32 NumGlobals 247fb81ec1a875d13d9750006313b9123903336101dStephen Hines V = M.getOrInsertGlobal(kRsGlobalProperties, Int32ArrayTy); 248fb81ec1a875d13d9750006313b9123903336101dStephen Hines llvm::GlobalVariable *GlobalProperties = 249fb81ec1a875d13d9750006313b9123903336101dStephen Hines llvm::dyn_cast<llvm::GlobalVariable>(V); 250fb81ec1a875d13d9750006313b9123903336101dStephen Hines llvm::Constant *GlobalPropertiesInit = 251fb81ec1a875d13d9750006313b9123903336101dStephen Hines llvm::ConstantDataArray::get(M.getContext(), GVProperties); 252fb81ec1a875d13d9750006313b9123903336101dStephen Hines GlobalProperties->setInitializer(GlobalPropertiesInit); 253fb81ec1a875d13d9750006313b9123903336101dStephen Hines GlobalProperties->setConstant(true); 254fb81ec1a875d13d9750006313b9123903336101dStephen Hines 255750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines if (kDebugGlobalInfo) { 256750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalEntries->dump(); 257750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalNames->dump(); 258750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalAddresses->dump(); 259750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines GlobalSizes->dump(); 260fb81ec1a875d13d9750006313b9123903336101dStephen Hines GlobalProperties->dump(); 261750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 262750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 263750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines // Upon completion, this pass has always modified the Module. 264750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines return true; 265750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines } 266750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines}; 267750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 268750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines} 269750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 270750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hineschar RSGlobalInfoPass::ID = 0; 271750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 272750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hinesstatic llvm::RegisterPass<RSGlobalInfoPass> X("embed-rs-global-info", 273750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines "Embed additional information about RenderScript global variables"); 274750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 275750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hinesnamespace bcc { 276750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 277750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hinesllvm::ModulePass * createRSGlobalInfoPass(bool pSkipConstants) { 278750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines return new RSGlobalInfoPass(pSkipConstants); 279750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines} 280750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines 281750ee65e129a2baef2dc5bb9ad210b45c9184926Stephen Hines} 282